' 不是类型 'User' 的子类型",firebase,flutter,dart,google-cloud-firestore,provider"/>

首页 > 解决方案 > Flutter & Provider, "类型'列表' 不是类型 'User' 的子类型"

问题描述

Flutter 在运行时抛出异常:当使用 StreamProvider 从 Firestore 检索数据时,“类型 'List' 不是类型 'User' 的子类型”。可以使用 .cast() 或 List.from() 对 'User' 中的数据强制执行类型安全,但这对断言没有影响。即使在“用户”中将有问题的列表定义为动态也不会改变错误。

我已经广泛阅读了这方面的内容,例如Github issuetypesafe DartStackOverflow。这些解决方案都没有帮助,所以希望这里有人可以帮助我。

最少的代码示例

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:provider/provider.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {


    return MaterialApp(
      title: 'Flutter Demo',
      home: StreamProvider<User>.value(
          value: userData,
          builder: (context, snapshot) {
            return MyHomePage(title: 'Demo Error');
          }
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    final User userData = Provider.of<User>(context) ?? []; // This asserts at runtime

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '$userData.name',
            ),
          ],
        ),
      ),
    );
  }
}

User _getUserFromSnapshot(DocumentSnapshot snapshot){

  List<String> categoriesFromDb = (snapshot.data['categories'] as List).cast<String>(); // Cast does not work

  return User(uid: '8GX2aGVn0GTrwLMxSZgx6STdnnA3',
    name: snapshot.data['name'],
    email: snapshot.data['email'],
    phone: snapshot.data['phoneNumber'],
    categories: categoriesFromDb,
    surname: snapshot.data['surname'],
  );

}

Stream<User> get userData{
  return Firestore.instance.collection('users')
      .document('8GX2aGVn0GTrwLMxSZgx6STdnnA3')
      .snapshots().map<User>(_getUserFromSnapshot);
}


class User {

  final String uid;
  final String name;
  final String surname;
  final String phone;
  final String email;
  final List<String> categories;

  User({this.uid, this.name, this.surname, this.email, this.phone, this.categories})
      : super();

}

重现步骤:

-> 使用 StreamProvider 从 Firestore 集合中检索字符串数组。

-> 将 Firestore 数据映射到自定义类型(在我的例子中是“用户”)。

-> Flutter 在运行时断言。

标签: firebaseflutterdartgoogle-cloud-firestoreprovider

解决方案


发生这种情况是因为初始 stat 没有数据,因此它返回 List 但您正尝试将其分配给 User 类型,因为您正面临此错误。

您可以通过检查 runtimeType 来解决,如下所示。

final User userData = Provider.of<User>(context).runtimeType == User
        ? Provider.of<User>(context)
        : null; 

推荐阅读