Home > Back-end >  How to read a specific item in map in firestore using flutter
How to read a specific item in map in firestore using flutter

Time:12-20

I am trying to read a map like the below image which is related to skills:

enter image description here

as to shows like the below one: enter image description here

and this is the method which brings me the userdata:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:haroonpf/enums/screen_state.dart';
import 'package:haroonpf/presentation/screens/home/models/skills.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;
  UserInfoSkillsModel? userSkillsModel;


  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);
  }
}

and this is the model I have:

class UserInfoModel {
  String? image;
  String? name;
  String? country;
  String? city;
  String? position;
  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 = json['skills'] != null ? UserSkills.fromJson(json['skills']) : null;
  }

  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'] = this.userSkills;
    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;
  }
}

and this is the view class I have:

import 'package:flutter/material.dart';
import 'package:haroonpf/presentation/screens/base_view_model.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.getUserData();
      },
      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: [
                Expanded(
                  child: AnimatedCircularProgressIndicator(
                    percentage: double.parse(homeViewModel.userSkillsModel!.fwo_percentage!),
                    label: "Flutter",
                  ),
                ),
                SizedBox(width: defaultPadding),
                Expanded(
                  child: AnimatedCircularProgressIndicator(
                    percentage: 0.8,
                    label: "Android \nStudio",
                  ),
                ),
                SizedBox(width: defaultPadding),
                Expanded(
                  child: AnimatedCircularProgressIndicator(
                    percentage: 0.65,
                    label: "Fire\n-base",
                  ),
                ),
              ],
            ),
          ),
        ],
      );}
    );
  }
}

So what I need is to read every skill name and percentage value related to each part..

CodePudding user response:

I think the issue is that skills is represented as a List<Map<String, dynamic>> rather than a Map<String, dynamic>. I have reworked your model slightly to take this into account.

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;
  }
}

CodePudding user response:

You can create a custom listView that you pass the Skill list that the firebase returns to you and then each item would be the widget that you want to paint with the name and the percentage

  • Related