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"
But when comment the birthday other data shows nicely.
I couldn't understand what's the error on fetching birthday.
database birthday parameter Screenshot
I want display only year , month and day
at the UI displaying this
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.