如何在firestore中显示地图列表并在颤动中显示它们

Posted

技术标签:

【中文标题】如何在firestore中显示地图列表并在颤动中显示它们【英文标题】:How to display a list of map in firestore and shows them in flutter 【发布时间】:2022-01-21 16:40:18 【问题描述】:

我有以下型号:

class UserInfoModel 
  String? image;
  String? name;
  String? country;
  String? city;
  String? position;
  List<UserSkills>? userSkills;
  UserInfoModel(
      this.image, this.name, this.country, this.position, this.userSkills);

  UserInfoModel.fromJson(dynamic json) 
    image = json['user_image'];
    name = json['name'];
    country = json['country'];
    city = json['city'];
    position = json['position'];
    userSkills = [
      for (final skill in json['skills'] ?? []) UserSkills.fromJson(skill),
    ];
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['user_image'] = this.image;
    data['name'] = this.name;
    data['country'] = this.country;
    data['city'] = this.city;
    data['position'] = this.position;
    data['skills'] = [for (final skill in this.userSkills ?? []) skill.toJson()];
    return data;
  


class UserSkills 
  String? skillName;
  String? skillPerc;

  UserSkills(this.skillName, this.skillPerc);

  UserSkills.fromJson(dynamic json) 
    skillName = json['skill_name'];
    skillPerc = json['skill_perc'];
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['skill_name'] = this.skillName;
    data['skill_perc'] = this.skillPerc;
    return data;
  

与下图火存储有关:

我尝试创建两种方法,一种读取用户信息,另一种读取用户技能,所以下面是我的代码:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:haroonpf/enums/screen_state.dart';
import 'package:haroonpf/presentation/screens/home/models/user_info.dart';
import 'package:haroonpf/utils/constants.dart';
import '../../base_view_model.dart';

class HomeViewModel extends BaseViewModel 
  UserInfoModel? userModel;
  List<UserSkills> userSkills = [];


  void getUserData() async 
    await FirebaseFirestore.instance
        .collection('users')
        .doc(uId)
        .get()
        .then((value) 
      // print("fbValues: " + value.data().toString());
      userModel = UserInfoModel.fromJson(value.data());
    ).catchError((error) 
      print(error.toString());
    );
    setState(ViewState.Idle);
  

  Future<List<UserSkills>> getUserSkills() async 
    CollectionReference getSkills =
    FirebaseFirestore.instance.collection('users');
    await getSkills.get().then((snapshot) 
      if (userSkills.isNotEmpty) userSkills.clear();
      snapshot.docs.forEach((element) 
        userSkills.add(UserSkills.fromJson(element.data()));
        print("my skills:" + element.data().toString());
      );
    );
    setState(ViewState.Idle);
    return userSkills;
  


所以在我的技能小部件类中,我尝试按以下代码检索数据:

import 'package:flutter/material.dart';
import 'package:haroonpf/presentation/screens/home/viewmodel/home_view_model.dart';
import 'package:haroonpf/utils/animation/animated_progress_indicator.dart';
import 'package:haroonpf/utils/constants.dart';

import '../../../../../base_screen.dart';

class Skills extends StatelessWidget 
  const Skills(
    Key? key,
  ) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return BaseScreen<HomeViewModel>(onModelReady: (homeViewModel) 
      homeViewModel.getUserSkills();
    , builder: (context, homeViewModel, _) 
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Divider(),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: defaultPadding),
            child: Text(
              "Framework out skills",
              style: Theme.of(context).textTheme.subtitle2,
            ),
          ),
          SingleChildScrollView(
            scrollDirection: Axis.vertical,
            child: Row(
              children: [
                ...homeViewModel.userSkills.map(
                  (skills) => Expanded(
                    child: AnimatedCircularProgressIndicator(
                      percentage: double.parse(skills.skillPerc!),
                      label: skills.skillName.toString(),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      );
    );
  

但我发现以下错误:

Unexpected null value.

所以似乎因为我没有引用文档 ID,所以当我尝试添加文档 ID 时它不起作用...

那么我怎样才能正确地将技能数据检索到AnimatedCircularProgressIndicator

【问题讨论】:

【参考方案1】:

意外的空值。

你知道是哪一行导致了这个错误吗?


我不确定我是否理解您对HomeViewModel 课程的态度。如果您修改 getUserData 以返回 Future&lt;UserInfoModel&gt;,那么您可以将其传递给您的 Skills 小部件中的 FutureBuilder

class HomeViewModel extends BaseViewModel 
  UserInfoModel? userModel;

  Future<UserInfoModel> getUserData() async 
    // not sure what setState does here but it was in the function to begin with
    setState(ViewState.Idle); 
    
    // here I am returning a cached userModel.
    // remove the following line of code if you don't actually want caching.
    if (userModel != null) return userModel;

    final value =
        await FirebaseFirestore.instance.collection('users').doc(uId).get();
    userModel = UserInfoModel.fromJson(value.data());
    return userModel;
  

然后在您的Skills 小部件中,创建FutureBuilder,然后在您的UserInfoModel 中循环List&lt;UserSkills&gt;

class Skills extends StatelessWidget 
  const Skills(
    Key? key,
  ) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return BaseScreen<HomeViewModel>(onModelReady: (homeViewModel) 
      // homeViewModel.getUserSkills();
    , builder: (context, homeViewModel, _) 
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Divider(),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: defaultPadding),
            child: Text(
              "Framework out skills",
              style: Theme.of(context).textTheme.subtitle2,
            ),
          ),
          FutureBuilder<UserInfoModel>(
            future: homeViewModel.getUserData(),
            builder: (context, snapshot) => SingleChildScrollView(
              scrollDirection: Axis.vertical,
              child: Row(
                children: [
                  // loop over the skills to display each one
                  for (final skill in snapshot.data?.userSkills ?? [])
                    Expanded(
                      child: AnimatedCircularProgressIndicator(
                        percentage: double.parse(skill.skillPerc!),
                        label: skill.skillName.toString(),
                      ),
                    ),
                ],
              ),
            ),
          ),
        ],
      );
    );
  

【讨论】:

哇!你今天拯救了我的一天,真的很有帮助:),非常感谢:)

以上是关于如何在firestore中显示地图列表并在颤动中显示它们的主要内容,如果未能解决你的问题,请参考以下文章

如何遍历地图列表并在颤动列表视图中显示文本小部件?

使用 StreamBuilder 获取 Firestore 文档,其中包含颤动中的地图列表

如何在listview颤动中显示来自firestore的图像数组?

颤动的firestore地理点未显示为标记

如何存储流数据并在颤动列表视图中显示新的和旧的?

如何在颤动的Listview中显示字符串列表