Flutter 类型 'Null' 不是类型 'String' 的子类型

Flutter , type 'Null' is not a subtype of type 'String'

我收到这个错误,我不知道为什么, 类型 'Null' 不是类型 'String' 的子类型 相关的导致错误的小部件是 StreamBuilder>

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:market_app/data/Models/single_product_class.dart';
import 'package:market_app/persentation/menu_screens/add_windows_screen.dart';

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

  @override
  State<WindowsScreen> createState() => _WindowsScreenState();
}

class _WindowsScreenState extends State<WindowsScreen> {
  CollectionReference windowsCollection =
      FirebaseFirestore.instance.collection("Products");
  List<Product> window = [];
  // WindowsProvider().windows;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context).push(MaterialPageRoute(
              builder: (contextt) => const AddWindowsScreen()));
        },
        child: const Icon(Icons.add),
        backgroundColor: Colors.blueAccent,
      ),
      body: StreamBuilder<QuerySnapshot>(
          stream: windowsCollection.snapshots(),
          builder: (context, snapshot) {
            for (var document in snapshot.data!.docs) {
              Map<String, dynamic> productFromFStore =
                  document.data()! as Map<String, dynamic>;
              
              window.add(Product.fromJson(productFromFStore));
              // window.last.id = document.id;

            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(
                child: CircularProgressIndicator(),
              );
            } else if (snapshot.connectionState == ConnectionState.done &&
                snapshot.data == null) {
              return const Center(
                child: Text(" no data to be showen "),
              );
            } else if (snapshot.hasError) {
              return const Text('Something went wrong');
            }

            return GridView.builder(
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2),
              itemBuilder: (context, i) => GridTile(
                header: ListTile(
                  leading: IconButton(
                    icon: const Icon(Icons.favorite),
                    onPressed: () {},
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.shopping_cart_outlined),
                    onPressed: () {},
                  ),
                ),
                child: Image.network(window[i].imageUrl,
                    fit: BoxFit.cover),

                // footer: Row(
                //   children: [
                //     Text(windows[i].name),
                //     const Spacer(
                //       flex: 1,
                //     ),s
                //     // Text(windows[i].price)
                //   ],
                // ),
              ),
              itemCount: snapshot.data?.docs.length,
            );
          }),
    );
  }
}

这是产品型号:

  import 'package:cloud_firestore/cloud_firestore.dart';

class Product {
  final String name;
  final String description;
  late String id;
  final double price;
  final int amount;
  final String imageUrl;

  Product(
      {required this.name,
      required this.description,
      required this.price,
      required this.amount,
      required this.imageUrl,
      id});

  factory Product.fromJson(Map<String, dynamic> data) {
    return Product(
      name: data["name"] ,
      description: data["description"],
      price: double.parse(data["price"]),
      amount: int.parse(data["amount"]),
      imageUrl: data["imageUrl"],
      id: data["id"],
    );
  }
  factory Product.fromSnapshot(DocumentSnapshot snap) {
    Map<String, dynamic> data = snap.data()! as Map<String, dynamic>;
    return Product(
      name: data["name"],
      amount: int.parse(data["amount"]),
      description: data["description"],
      imageUrl: data["imageUrl"],
      price: double.parse(data["price"]),
      id: data["id"],
    );
  }

  Map<String, dynamic> toMap(Product product) {
    return {
      "name": name,
      "description": description,
      "price": price,
      "amount": amount,
      "imageUrl": imageUrl,
      "id": id,
    };
  }
}

我尝试了其他方法来获取数据,例如 // child: Image。网络( snapshot.data!.docs[索引].data().toString()) 但是我只有字符串,但我仍然不知道如何修复它,所以我需要一些帮助

是的,亲爱的 null 在 Flutter 中给你一个错误。您需要为变量分配任何值。它会解决你的错误。它给出了一个错误,因为您使用了 QuerySnapshot 对象并且它需要一些值。如果该值为空,它将给您一个错误。给它赋值解决错误。

问题来自parse方法,您可以在解析数据之前检查是否为空。例如:

...

price: data["price"] == null ? 0 : double.parse(data["price"]),
amount: data["amount"] == null ? 0 : int.parse(data["amount"]),

...

或者您可以使用这个辅助方法:

num parseNum(String? value) => value == null ? 0 : num.parse(value);

用法:

...

price: parseNum(data["price"]),
amount: parseNum(data["amount"]),

...