Home > database >  I need help understanding Streambuilder; why is my data not appearing?
I need help understanding Streambuilder; why is my data not appearing?

Time:09-28

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.

  • Related