Flutter StreamProvider 'List<dynamic>' 不是类型转换中类型 'List<??>' 的子类型

Posted

技术标签:

【中文标题】Flutter StreamProvider \'List<dynamic>\' 不是类型转换中类型 \'List<??>\' 的子类型【英文标题】:Flutter StreamProvider 'List<dynamic>' is not a subtype of type 'List<??>' in type castFlutter StreamProvider 'List<dynamic>' 不是类型转换中类型 'List<??>' 的子类型 【发布时间】:2020-10-21 09:49:13 【问题描述】:

我正在尝试使用 StreamProvider 使来自 firestore 文档流的数据在我的整个应用程序中可用。它是一个食谱应用程序,这是购物清单。

我有一个模型 RecipeItem ,其中包含有关配方中项目的详细信息。 firestore 文档包含一个值,它是一个数组,称为“列表”,其中包含列表中每个项目的映射。

以下是我与 Firestore 的连接和设置流。我尝试获取文档,然后用户映射为列表中的每个项目创建一个 RecipeItem 实例。方法如下:

Stream<List<RecipeItem>> getPersonalList() 
    print('Fetching personal list');

    return _db.collection('shopping_lists').document(userId).snapshots().map(
          (DocumentSnapshot documentSnapshot) => documentSnapshot.data['list']
              .map(
                (item) =>
                    // print(item);
                    RecipeItem(
                  category: item['category'],
                  wholeLine: item['wholeLine'],
                  recipeTitle: item['recipeTitle'],
                  recipeId: item['recipeId'],
                  purchased: item['purchased'],
                ),
              )
              .toList(),
        );
  

现在在 main.dart 中,我有一个 StreamProvider 来查找类型 &lt;List&lt;RecipeItem&gt;&gt;

class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MultiProvider(
      providers: [
        StreamProvider<FirebaseUser>(
            //Access withing the app -> var user = Provider.of<FirebaseUser>(context);
            create: (_) => AuthService().user),
        StreamProvider<List<RecipeItem>>(
          create: (_) => PersonalListDB().getPersonalList(),
          catchError: (context, error) 
            print('This is the error from stream provider *** $error');
          ,
        ),
        ChangeNotifierProvider(
          create: (_) => RecipesDB(),
        )
      ],
      child: MaterialApp(
etc etc...

当我运行它时,我得到了这个错误:

类型“列表”不是类型转换中“列表”类型的子类型

我可以解决此问题的唯一方法是,如果我将 List&lt;RecipeItem&gt; 的所有位置更改为 List&lt;dynamic&gt;。这可行,但似乎不是正确的解决方案。

我已经尝试了几(一百万)件事情。

我在这里找到了这篇文章:Getting type 'List<dynamic>' is not a subtype of type 'List<...>' error in JSON

这告诉我 .toList() 可能是问题,因为它创建了 List。所以我尝试使用 List.from 和使用 .cast 但没有运气。更让我困惑的是,我非常关注其他教程做类似的事情。

非常感谢任何解决此问题并帮助我理解问题的帮助。

【问题讨论】:

试图返回:作为 List 【参考方案1】:

Firestore 列表(db、httpRequest 等)的类型是动态的,以避免在调用它们时出现问题,您可以尝试告诉地图您要投射对象的类型

return _db.collection('shopping_lists').document(userId).snapshots().map<List<RecipeItem>>( //I'm not sure what kind of object this map should return, is this the method map part of the stream? if it is then it should be of type List<RecipeItem>
      (DocumentSnapshot documentSnapshot) => documentSnapshot.data['list']
          .map<RecipeItem>( //now it will know it's not a dynamic value but of type RecipeItem
            (item) =>
                // print(item);
                RecipeItem(
              category: item['category'],
              wholeLine: item['wholeLine'],
              recipeTitle: item['recipeTitle'],
              recipeId: item['recipeId'],
              purchased: item['purchased'],
            ),
          )
          .toList(),
);

【讨论】:

在第二张地图上添加 很有效。感谢您的解决方案和解释。

以上是关于Flutter StreamProvider 'List<dynamic>' 不是类型转换中类型 'List<??>' 的子类型的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:如何处理使用 StreamProvider、FireStore 和使用 Drawer

Flutter Riverpod:使用 StreamProvider 返回 2 个流

Flutter:StreamProvider 的奇怪行为,使用不完整数据重建的小部件

Flutter Provider,当他的参数改变时更新 StreamProvider

如何在 Flutter (Dart) 中通过新路由获取子级 StreamProvider 数据

Flutter:带有 onAuthStateChanged 的​​ StreamProvider<FirebaseUser> 始终返回 null 作为第一个值