skip to Main Content

I am trying to learn how to use Firebase through a lesson on YT. But I cannot get it to work.

What happens:

  • The " if (snapshot.hasError) is true and returns:

Something went wrong! type ‘Null’ is not a subtype f type ‘String’

  • But I can see in my Firebase console that it is trying to read/access the database.
  • And i have checked that my Json names are corresponding to those in the firebase console.

My conclusion from that:
My code is the problem. Specifically something about my readFruits function.

I cannot seem to figure out what I have missed. Can you see something I am missing or that I am doing wrong?

This is all of my code.

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: StreamBuilder<List<Fruit>>(
        stream: readFruits(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Text('Something went wrong! ${snapshot.error}');
          } else if (snapshot.hasData) {
            final fruit = snapshot.data!;
            return ListView(
              children: fruit.map(buildFruit).toList(),
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

Stream<List<Fruit>> readFruits() => FirebaseFirestore.instance.collection('Fruits').snapshots().map(
      (snapshot) => snapshot.docs.map((doc) => Fruit.fromJson(doc.data())).toList(),
    );


Widget buildFruit(Fruit fruit) => ListTile(
      title: Text(fruit.fruit),
      subtitle: Text(fruit.colour),
    );


class Fruit {
  final String fruit;
  final String colour;
  const Fruit({required this.colour, required this.fruit});

  static Fruit fromJson(Map<String, dynamic> json) => Fruit(
        fruit: json['type'],
        colour: json['colour'],
      );

  Map<String, dynamic> toJson() => {'type': fruit, 'colour': colour};
}

2

Answers


  1. Chosen as BEST ANSWER

    The problem was that when I double-checked the JSON keys, I didn't notice that I had put them inside a map in the firebase console. So it is not weird that my code was nonfunctional.

    I just thought the "Fruits" was a header...

    Georgina's Answer would also have solved it if had more documents with some correct and some incorrect.

    See the "Fruits" subheader, that means its a map


  2. I think your not accounting for null cases when your data is returned from Firebase. Try this:

    static Fruit fromJson(Map<String, dynamic> json) => Fruit(
            fruit: json['type'] ?? "",
            colour: json['colour'] ?? "",
          );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search