skip to Main Content

I’m developing an app that manages glossary food items. I can’t figure out what is the mistake I’ve done. Here’s my code…

First, I’ve created a class called ‘Product’ that contains all the required fields like Product name, Product Image, item Type and quantity etc

The model :

class Product {
  String id;
  final String productName;
  final String itemType;
  final String productImage;
  final String purchasedDate;
  final String expiryDate;
  final String quantity;

  Product({
    this.id = '',
    required this.productName,
    required this.productImage,
    required this.itemType,
    required this.purchasedDate,
    required this.expiryDate,
    required this.quantity,
  });

  Map<String, dynamic> toJson() => {
        'id': id,
        'ProductImage': productImage,
        'ProductName': productName,
        'PurchasedDate': purchasedDate,
        'ExpiryDate': expiryDate,
        'ItemType': itemType,
        'Quantity': quantity,
      };

  static Product fromJson(Map<String, dynamic> json) => Product(
      productName: json['ProductName'],
      productImage: json['productImage'],
      itemType: json['ItemType'],
      purchasedDate: json['purchasedDate'],
      expiryDate: json['ExpiryDate'],
      quantity: json['Quantity']);
}

The code for implementation :

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:expire_x/utils/product.dart';
import 'package:flutter/material.dart';

class HomePageTwo extends StatefulWidget {
  const HomePageTwo({Key? key}) : super(key: key);

  @override
  State<HomePageTwo> createState() => _HomePageTwoState();
}

class _HomePageTwoState extends State<HomePageTwo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("home page"),
      ),
      body: StreamBuilder<List<Product>>(
        stream: readProduct(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Text("Something went wrong> ${snapshot.error}");
          } else if (snapshot.hasData) {
            final product = snapshot.data!;
            return ListView(
              children: product.map(buildProduct).toList(),
            );
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }

  Widget buildProduct(Product product) => ListTile(
        title: Text(product.productName),
      );

  Stream<List<Product>> readProduct() => FirebaseFirestore.instance
      .collection('Products')
      .snapshots()
      .map((snapshot) =>
          snapshot.docs.map((doc) => Product.fromJson(doc.data())).toList());

  Future CreateProduct() async {
    final docProduct = FirebaseFirestore.instance.collection('Products').doc();

    final product = Product(
      id: docProduct.id,
      productImage: 'ddd',
      productName: "productName",
      purchasedDate: "purchasedDate",
      expiryDate: "expiryDate",
      itemType: "itemType",
      quantity: "quantity",
    );
    final json = product.toJson();
    await docProduct.set(json);
  }
}

The json response from firebase that I wanted :
json response

And the error :

type ‘Null’ is not a subtype of type ‘String’

In the emulator

I’m new to flutter. Can anyone please help me?

2

Answers


  1. Typo mistake in your model class

    static Product fromJson(Map<String, dynamic> json) => Product(
      productName: json['ProductName'],
      productImage: json['ProductImage'],       // It should be 'ProductImage'
      itemType: json['ItemType'],
      purchasedDate: json['PurchasedDate'],    // and this should be 'PurchasedDate'
      expiryDate: json['ExpiryDate'],
      quantity: json['Quantity']);
    
    Login or Signup to reply.
  2. This error occurs when you add required keyword in the constructor. And one of the value appears to be null.

    To overcome this

    • Make sure that all the fields in all the documents is filled.

    OR

    • Avoid using required use null operator instead ? if you are not sure the documents to be filled everytime.

    Like:

    class Product {
      String? id;
      String? productName;
      String? itemType;
      String? productImage;
      String? purchasedDate;
      String? expiryDate;
      String? quantity;
    
      Product({
        this.id = '',
        this.productName,
        this.productImage,
        this.itemType,
        this.purchasedDate,
        this.expiryDate,
        this.quantity,
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search