I am attempting (via following a short online tutorial) to build a simple form in Flutter that saves a name, age, and birthday to my Firestore database. The form works correctly as I can watch the documents being added in real-time via the console. However, when I move to the next part of the tutorial (reading data), I am running into an error with the Streambuilder call. The code shows no errors (i.e. squiggly red underlines) but I'm getting an error ('Type "Null" is not a subtype of type "String") when I run the app. Seems pretty obvious my call to the database is not returning the data I'm looking for, but I don't understand why. Any guidance would be a big help.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flipbooks/screens/milke_form.dart';
import 'package:flutter/material.dart';
import '../misc/user.dart';
class MilkeMainPage extends StatefulWidget {
const MilkeMainPage({super.key});
@override
State<MilkeMainPage> createState() => _MilkeMainPageState();
}
class _MilkeMainPageState extends State<MilkeMainPage> {
final controller = TextEditingController();
Widget buildUser(User user) => ListTile(
leading: CircleAvatar(child: Text('$user.age')),
title: Text(user.name),
subtitle: Text(user.birthday.toIso8601String()),
);
Stream<List<User>> readUsers() => FirebaseFirestore.instance
.collection('users')
.snapshots()
.map((snapshot) =>
snapshot.docs.map((doc) => User.fromJson(doc.data())).toList());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('All Users')),
body: StreamBuilder<List<User>>(
stream: readUsers(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong! ${snapshot.error}');
} else if (snapshot.hasData) {
final users = snapshot.data!;
return ListView(
children: users.map(buildUser).toList(),
);
} else {
return const Center(child: CircularProgressIndicator());
}
}),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const MilkeForm(),
));
},
),
);
}
}
// USER CLASS CODE
import 'package:cloud_firestore/cloud_firestore.dart';
class User {
String id;
final String name;
final int age;
final DateTime birthday;
User({
this.id = '',
required this.name,
required this.age,
required this.birthday,
});
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'age': age,
'birthday': birthday,
};
static User fromJson(Map<String, dynamic> json) => User(
id: json['id'],
name: json['name'],
age: json['age'],
birthday: (json['birthday'] as Timestamp).toDate(),
);
}
CodePudding user response:
Try to accept null value while getting data like, while the issue with String
is getting null;
class User {
String? id;
final String? name;
final int age;
final DateTime birthday;
static User fromJson(Map<String, dynamic> json) => User(
id: json['id'],
name: json['name'],
age: json['age'],
birthday: (json['birthday'] as Timestamp).toDate(),
);
CodePudding user response:
Issue resolved...user error :). I had a couple of old documents in the collection that were missing field ID's - so the Stream was getting 'null' when it tried to access the docs. Deleted those documents and all is well now. Thanks for your help.