Home > Software engineering >  I tried to display 'DateTime' on flutter UI get from firestore but show " Bad state:
I tried to display 'DateTime' on flutter UI get from firestore but show " Bad state:

Time:01-29

I have to do some changes in my previous question because of that now user birthday (year ,month and day ) not display at the UI and also show this error at the console " E/flutter ( 7311): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform"

error enter image description here

But when comment the birthday other data shows nicely.

I couldn't understand what's the error on fetching birthday.

database birthday parameter Screenshot

enter image description here

I want display only year , month and day

at the UI displaying this

enter image description here

code

model class

class Users {
  String? id;
  String? name;
  String? url;
  DateTime? birthday;

  Users({
    this.id,
    this.name,
    this.url,
    this.birthday,
  });

  Users.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    url = json['url'];
    birthday = json["birthday"]?.toDate();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['url'] = this.url;
    data['birthday'] = this.birthday;
    return data;
  }
}

controller class



User? user = FirebaseAuth.instance.currentUser;
UserModel loggedInUser = UserModel();
@override
Future<List<Users>> fetchRecords() async {
  var records = await FirebaseFirestore.instance.collection('Users').get();
  return mapRecords(records);
}

List<Users> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
  var list = records.docs
      .map(
        (user) => Users(
          id: user.id,
          name: user['name'],
          url: user['url'],
           birthday: user['birthday'].toDate(),
        ),
      )
      .toList();

  return list;
}

Ui code

SizedBox(
  child: SizedBox(
      width: width * 0.94,
      height: height * 0.95,
      child: FutureBuilder<List<Users>>(
          future: fetchRecords(),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              List<Users> data = snapshot.data ?? [];

              return ListView.builder(
                  itemCount: data.length,
                  itemBuilder: (context, index) {
                    return (SizedBox(
                      height: 100,
                      child: Card(
                        color:
                            Colors.white.withOpacity(0.8),
                        shape: RoundedRectangleBorder(
                          side: const BorderSide(
                            color: Colors.greenAccent,
                          ),
                          borderRadius:
                              BorderRadius.circular(20.0),
                        ),
                        child: Column(
                          children: <Widget>[
                            ListTile(
                                leading: Image.network(
                                  '${data[index].url}',
                                  height: 30,
                                  fit: BoxFit.cover,
                                ),
                                title: Text(
                                    '${data[index].name}' ??
                                        ' '),
                                        subtitle: Text(
                                    '${data[index].birthday?.year}/${data[index].birthday?.month}/${data[index].birthday?.day}'),
                                trailing: ElevatedButton(
                                  child: Text('View'),
                                  onPressed: () {
                                    
                                  },
                                ))
                          ],
                        ),
                      ),
                    ));
                  });
            }
          }))),

How to solve this error and fetch user birthday ?

CodePudding user response:

I have Recreated the setup from the code you have provided and Your UI code is on point but your fetchRecords() can use some Typing CollectionReference and DocumentReference so try the below code as it shown me the correct birthday into the UI

model class:

class Users {
  final String id; final String name; final String url; final DateTime birthday;

  Users({
    required this.id, required this.name, required this.url, required this.birthday,
  });

  Users.fromJson(Map<String, dynamic> json)
      : this(
            id: json['id']! as String, 
            name: json['name']! as String, 
            url: json['url']! as String,
            birthday: DateTime.fromMillisecondsSinceEpoch(json['birthday'].toInt()));

  Map<String, Object?> toJson() {
    return {'id': id, 'name': name, 'url': url, 'birthday': birthday.millisecondsSinceEpoch};
  }
}

And the fetchRecords() and mapRecords() will be:

User user = FirebaseAuth.instance.currentUser!;
UserModel loggedInUser = UserModel();

Future<List<Users>> fetchRecords() async {
    final usersRef =
        FirebaseFirestore.instance.collection('users').withConverter<Users>(
              fromFirestore: (snapshot, _) => Users.fromJson(snapshot.data()!),
              toFirestore: (user, _) => user.toJson(),
            );

    QuerySnapshot<Users> users = await usersRef.get();
    return mapRecords(users);
  }

List<Users> mapRecords(QuerySnapshot<Users> records) {
    var list = records.docs
        .map(
          (user) => Users(
            id: user.id, 
            name: user['name'], 
            url: user['url'], 
            birthday: user['birthday'].toDate(),
          ),
        ).toList();
    return list;
  }

In my opinion for some reason It is best to use FlutterFire provided Typed class technique rather than using any custom Typed technique.

  • Related