Firebase 颤振-使用提供程序和Firestore返回空列表

Firebase 颤振-使用提供程序和Firestore返回空列表,firebase,flutter,google-cloud-firestore,provider,Firebase,Flutter,Google Cloud Firestore,Provider,我正在尝试使用Firebase中的数据创建一个列表。然后我想将此列表传递到我的应用程序的各个部分。当我运行代码并测试该元素时,结果显示为空列表。这是我的密码。我首先创建一个服务类: class OccasionServices { FirebaseFirestore _firestore = FirebaseFirestore.instance; Future<List<String>> getAllOccasions(currentUser) async =&

我正在尝试使用Firebase中的数据创建一个列表。然后我想将此列表传递到我的应用程序的各个部分。当我运行代码并测试该元素时,结果显示为空列表。这是我的密码。我首先创建一个服务类:

class OccasionServices {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<List<String>> getAllOccasions(currentUser) async => _firestore
          .collection('collections')
          .doc(currentUser)
          .collection('occasions')
          .get()
          .then((snap) {
        List<String> allOccasions = [];
        snap.docs.forEach((snapshot) => snapshot
            .data()
            .entries
            .map((mapEntry) => allOccasions.add((mapEntry.value))));
        return allOccasions;
      });
}
但当我在应用程序的另一部分使用此列表时,我只能访问一个空列表:

Widget build(BuildContext context) {
  final collectionProvider = Provider.of<CollectionProvider>(context);
  final collections = collectionProvider.allOccasions;
  print(collections);
  return Scaffold(
    appBar: AppBar(
      backgroundColor: Colors.deepPurpleAccent,
      title: Text('Viewer'),
    ),
    body: Container(
      child: Text('body'),
    ),
  );
}

有什么建议吗?谢谢

我会尝试这种方法:

class OccasionServices {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<List<String>> getAllOccasions(currentUser) async => _firestore
          .collection('collections')
          .doc(currentUser)
          .collection('occasions')
          .get()
          .then((snap) =>
             snap.docs
              .map((doc) => doc.data().values.cast<String>())
              .expand((e) => e).toList()
          )
}
类偶然事件服务{
FirebaseFirestore _firestore=FirebaseFirestore.instance;
未来GetAllocations(currentUser)异步=>\u firestore
.collection(“collections”)
.doc(当前用户)
.collection(“场合”)
.get()
。然后((捕捉)=>
snap.docs
.map((doc)=>doc.data().values.cast())
.expand((e)=>e.toList()
)
}
一步一步地做每件事:

/// this will convert each doc in the docs List and return a new List of what is inside,
/// it will get all the values of the Map<String dynamic> returned by data() as a List<dynamic>
/// then you will cast them to String with .cast<String> (you have to be sure each value can be casted to String or it will throw)
.map((doc) => doc.data().values.cast<String>())
///这将转换文档列表中的每个文档,并返回其中内容的新列表,
///它将以列表的形式获取data()返回的映射的所有值
///然后您将使用.cast将它们转换为字符串(您必须确保每个值都可以转换为字符串,否则它将抛出)
.map((doc)=>doc.data().values.cast())
在此之前,您有一个
QuerySnapshot
,它有一个
QueryDocumentSnapshot
列表,每个
QueryDocumentSnapshot
都有一个
映射
,因此您有一个
列表
,该列表中的内容被转换为
列表
,所以现在您有了一个
列表
,但您需要一个
列表
,不是嵌套列表,因此您可以使用运算符
expand
,该运算符可用于展平列表,它“扩展”了列表中的内容,因此结果将是一个
列表


最后请注意,如果您的文档可以保存与字符串不同的数据,您可以尝试使用
whereType()
而不是
cast()
来仅保留字符串值,我将尝试以下方法:

class OccasionServices {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<List<String>> getAllOccasions(currentUser) async => _firestore
          .collection('collections')
          .doc(currentUser)
          .collection('occasions')
          .get()
          .then((snap) =>
             snap.docs
              .map((doc) => doc.data().values.cast<String>())
              .expand((e) => e).toList()
          )
}
类偶然事件服务{
FirebaseFirestore _firestore=FirebaseFirestore.instance;
未来GetAllocations(currentUser)异步=>\u firestore
.collection(“collections”)
.doc(当前用户)
.collection(“场合”)
.get()
。然后((捕捉)=>
snap.docs
.map((doc)=>doc.data().values.cast())
.expand((e)=>e.toList()
)
}
一步一步地做每件事:

/// this will convert each doc in the docs List and return a new List of what is inside,
/// it will get all the values of the Map<String dynamic> returned by data() as a List<dynamic>
/// then you will cast them to String with .cast<String> (you have to be sure each value can be casted to String or it will throw)
.map((doc) => doc.data().values.cast<String>())
///这将转换文档列表中的每个文档,并返回其中内容的新列表,
///它将以列表的形式获取data()返回的映射的所有值
///然后您将使用.cast将它们转换为字符串(您必须确保每个值都可以转换为字符串,否则它将抛出)
.map((doc)=>doc.data().values.cast())
在此之前,您有一个
QuerySnapshot
,它有一个
QueryDocumentSnapshot
列表,每个
QueryDocumentSnapshot
都有一个
映射
,因此您有一个
列表
,该列表中的内容被转换为
列表
,所以现在您有了一个
列表
,但您需要一个
列表
,不是嵌套列表,因此您可以使用运算符
expand
,该运算符可用于展平列表,它“扩展”了列表中的内容,因此结果将是一个
列表


最后一点,如果您的文档可以保存不同于字符串的数据,您可以尝试使用
whereType()
而不是
cast()
来仅保留字符串值,您可以在
notifyListeners()之前打印_occasionServices.getAllocations的返回吗。例如,通过添加print(“\u getAllocations:$\u Allocations”);嗨,dumazy,这也会返回一个空列表。这一定意味着OccasionServices中的GetAllocations函数有问题。我将从那里开始调查。更新:我的firestore查询返回了一些文档快照。我认为问题可能出在函数的“映射”部分。你能修复函数的“映射”部分吗?如果没有,我可以给你一个解决方案。嗨,奇切贝,我还没能解决它。如果您能帮助我,我将不胜感激。您好,您能在
notifyListeners()之前打印_occasionServices.getAllocations的返回吗。例如,通过添加print(“\u getAllocations:$\u Allocations”);嗨,dumazy,这也会返回一个空列表。这一定意味着OccasionServices中的GetAllocations函数有问题。我将从那里开始调查。更新:我的firestore查询返回了一些文档快照。我认为问题可能出在函数的“映射”部分。你能修复函数的“映射”部分吗?如果没有,我可以给你一个解决方案。嗨,奇切贝,我还没能解决它。如果您能帮助我,我将不胜感激。谢谢您如此全面的回答。绝对帮助我更好地理解这个过程!谢谢你这么全面的回答。绝对帮助我更好地理解这个过程!
/// this will convert each doc in the docs List and return a new List of what is inside,
/// it will get all the values of the Map<String dynamic> returned by data() as a List<dynamic>
/// then you will cast them to String with .cast<String> (you have to be sure each value can be casted to String or it will throw)
.map((doc) => doc.data().values.cast<String>())