【问题标题】:Converting QueryDocumentSnapshot to model type causes exception将 QueryDocumentSnapshot 转换为模型类型会导致异常
【发布时间】:2021-10-08 16:33:42
【问题描述】:

我正在使用 Firestore 查询填充 ListView.builder,然后我可以使用 TextField 控制器过滤项目,

这是 ListView.builder 小部件之前的代码:

class ListaUsuarios extends StatefulWidget {
  const ListaUsuarios({Key key}) : super(key: key);

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

class _ListaUsuariosState extends State<ListaUsuarios> {
  TextEditingController _controller = new TextEditingController();
  List _allResults = [];
  List _usuariosFiltrados = [];



  Future resultsLoaded;
  
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller.addListener(_onSearchChanged);
  }

  void didChangeDependencies(){
    super.didChangeDependencies();
    resultsLoaded = getUsuariosSnapShot();

  }

  getUsuariosSnapShot() async {
    var data = await FirebaseFirestore.instance
        .collection("users")
        .orderBy("username")
        .get();
    setState(() {
      _allResults = data.docs;
    });
    searchResultsList();
    return "complete";

  }
  void _onSearchChanged() {
    searchResultsList();

    print(_controller.text);
  }
  searchResultsList(){
    var showResults = [];
    if(_controller.text != ""){
      //tenemos parametro de busqueda
      var busqueda = _controller.text.toLowerCase();
      for (var usuarioSnaphot in _allResults) {
        var username = Usuario
            .fromSnapshot(usuarioSnaphot).username.toLowerCase();
        var about = Usuario
            .fromSnapshot(usuarioSnaphot).about.toLowerCase();
        var city = Usuario
            .fromSnapshot(usuarioSnaphot).city.toLowerCase();
        var country = Usuario
            .fromSnapshot(usuarioSnaphot).country.toLowerCase();
        var email = Usuario
            .fromSnapshot(usuarioSnaphot).email.toLowerCase();
        var first_name = Usuario
            .fromSnapshot(usuarioSnaphot).first_name.toLowerCase();
        var last_name = Usuario
            .fromSnapshot(usuarioSnaphot).last_name.toLowerCase();
        var web = Usuario
            .fromSnapshot(usuarioSnaphot).web.toLowerCase();

        if (username.contains(busqueda) || about.contains(busqueda) || city.contains(busqueda) || country.contains(busqueda) || email.contains(busqueda) || first_name.contains(busqueda) || last_name.contains(busqueda) || web.contains(busqueda)){
          showResults.add(usuarioSnaphot);
        }
      }
    }
    else{
      showResults = List.from(_allResults);
    }
    setState(() {
      _usuariosFiltrados = showResults;

    });
  }
  @override
  Widget build(BuildContext context) {

    print("estoy en lista de uusarioas");
    return Scaffold(
      appBar: AppBar(
        backgroundColor: AppColors.rojoMovMap,
        title: Text("Usuarios Mov-Map")
      ),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text("La búsqueda actual se ejecuta buscando en los campos: about, city, country, email, first_name, last_name y web",style: TextStyle(fontSize: 14,color: Colors.black38, fontStyle: FontStyle.italic),),

            ),
             Padding(
               padding: const EdgeInsets.all(8.0),
               child: Row(
                 children: [
                   Text("Si quieres buscar por otros tipos",style: TextStyle(fontSize: 14,color: Colors.black38, fontStyle: FontStyle.italic),),
                   Spacer(),
                   RaisedButton(
                     child: Text('Otras búsquedas \nde usuarios',style: TextStyle(color: Colors.white,fontSize: 13),),
                     color: Colors.red,
                     shape: RoundedRectangleBorder(
                         borderRadius: BorderRadius.all(Radius.circular(16.0))),
                     onPressed: () {
                       Navigator.push(
                         context,
                         MaterialPageRoute(builder: (context) => ListaUsuarios()),
                       );

                     },
                   )
                 ],
               ),
             ),
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                prefixIcon: Icon(Icons.search),
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: _usuariosFiltrados.length,

                  itemBuilder: (BuildContext context, int index){

这里有 Usuario.fromSnapshot 的声明:

Usuario.fromSnapshot(DocumentSnapshot snapshot)
      : about = snapshot['about'],
        city = snapshot['city'],
        country = snapshot['country'],
        email = snapshot['email'],
        email_verified = snapshot['email_verified'],
        first_name = snapshot['first_name'],
        is_active = snapshot['is_active'],
        is_ambassador = snapshot['is_ambassador'],
        is_business = snapshot['is_business'],
        is_movmap_admin = snapshot['is_movmap_admin'],
        last_name = snapshot['last_name'],
        profile_background = snapshot['profile_background'],
        profile_image = snapshot['profile_image'],
        sex = snapshot['sex'],
        tel = snapshot['tel'],
        tel_verified = snapshot['tel_verified'],
        token_firebase = snapshot['token_firebase'],
        userId = snapshot['userId'],
        username = snapshot['username'],
        web = snapshot['web'];

一切正常,我正在获取 Firestore 文档快照并将它们显示在列表视图中,但现在我需要选择其中一个项目并在详细信息页面/屏幕中显示它们的数据值,以便编辑一些然后如果需要。

我的问题是我正在尝试将项目值传递到详细信息页面/屏幕,如下所示:

RaisedButton(
                            child: Text('Editar este usuario',style: TextStyle(color: Colors.white,fontSize: 20),),
                            color: Colors.red,
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.all(Radius.circular(16.0))),
                            onPressed: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(builder: (context) => EditarUsuario(usuario: _usuariosFiltrados[index]),),
                              );

                            },
                          )

页面/类 EditarUsuario 需要一个 Usuario 类型的 var 来编辑值,但是当单击按钮导航到详细信息页面时会显示异常:

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following _TypeError was thrown building Builder(dirty):
flutter: type 'QueryDocumentSnapshot' is not a subtype of type 'Usuario'
flutter:

【问题讨论】:

    标签: flutter dart google-cloud-firestore


    【解决方案1】:

    使用从 _usuariosFiltrados[index].data() 返回 Usuario 的工厂。

    class Usuario {
      final String about;
      final String country;
      final String email;
      final bool email_verified;
      final String first_name;
      final bool is_active;
      final bool is_ambassador;
      final bool is_business;
      final bool is_movmap_admin;
      final String last_name;
      final String profile_background;
      final String profile_image;
      final String sex;
      final String tel;
      final bool tel_verified;
      final String token_firebase;
      final String userId;
      final String username;
      final String web;
    
      Usuario(
          {required this.about,
          required this.country,
          required this.email,
          required this.email_verified,
          required this.first_name,
          required this.is_active,
          required this.is_ambassador,
          required this.is_business,
          required this.is_movmap_admin,
          required this.last_name,
          required this.profile_background,
          required this.profile_image,
          required this.sex,
          required this.tel,
          required this.tel_verified,
          required this.token_firebase,
          required this.userId,
          required this.username,
          required this.web});
    
      Map<String, dynamic> toMap() {
        return {
          'about': about,
          'country': country,
          'email': email,
          'email_verified': email_verified,
          'first_name': first_name,
          'is_active': is_active,
          'is_ambassador': is_ambassador,
          'is_business': is_business,
          'is_movmap_admin': is_movmap_admin,
          'last_name': last_name,
          'profile_background': profile_background,
          'profile_image': profile_image,
          'sex': sex,
          'tel': tel,
          'tel_verified': tel_verified,
          'token_firebase': token_firebase,
          'userId': userId,
          'username': username,
          'web': web,
        };
      }
    
      factory Usuario.fromMap(Map<String, dynamic> map) {
        return Usuario(
          about: map['about'] as String,
          country: map['country'] as String,
          email: map['email'] as String,
          email_verified: map['email_verified'] as bool,
          first_name: map['first_name'] as String,
          is_active: map['is_active'] as bool,
          is_ambassador: map['is_ambassador'] as bool,
          is_business: map['is_business'] as bool,
          is_movmap_admin: map['is_movmap_admin'] as bool,
          last_name: map['last_name'] as String,
          profile_background: map['profile_background'] as String,
          profile_image: map['profile_image'] as String,
          sex: map['sex'] as String,
          tel: map['tel'] as String,
          tel_verified: map['tel_verified'] as bool,
          token_firebase: map['token_firebase'] as String,
          userId: map['userId'] as String,
          username: map['username'] as String,
          web: map['web'] as String,
        );
      }
    }
    
    

    然后

    Navigator.push(context,MaterialPageRoute(
    builder:(context)=>EditarUsuario(usuario: Usuario.fromMap(_usuariosFiltrados[index].data())),),);
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 2019-12-30
      相关资源
      最近更新 更多