Search code examples
flutterdartfirebase-realtime-databaseflutter-dependenciesdart-null-safety

i get errors when I fetch my data from an API using http.get()


I am facing this issue in my code and I am not able to solve it. I`m trying to fetch data through an API, and I get these errors in my IDE.

    [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
#0      Products.fetchAndSetProducts.<anonymous closure> (package:shop_app/providers/products_provider.dart:85:28)
#1      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:400:8)
#2      Products.fetchAndSetProducts (package:shop_app/providers/products_provider.dart:81:21) <asynchronous suspension>

The errors above points at this function

Future<void> fetchAndSetProducts() async {
    final url = Uri.parse(
      'https://flutter-update-607c9-default-rtdb.firebaseio.com/products.json',
    );
    try {
      final response = await http.get(url);
      final extractedData = json.decode(response.body) as Map<String, dynamic>;
      final List<Product> loadedProducts = [];
      extractedData.forEach((prodId, prodData) {
        loadedProducts.add(
          Product(
            id: prodId,
            title: prodData['title'],
            description: prodData['description'],
            price: prodData['price'],
            isFavorite: prodData['isFavorite'],
            imageUrl: prodData['imageUrl'],
          ),
        );
      });
      _items = loadedProducts;
      notifyListeners();
    } catch (error) {
      rethrow;
    }
  }

And here is my Product class

class Product with ChangeNotifier {
  final String? id;
  final String title;
  final String description;
  final double price;
  final String imageUrl;
  bool isFavorite;

  Product(
      {required this.id,
      required this.title,
      required this.description,
      required this.price,
      required this.imageUrl,
      this.isFavorite = false});
}

any help would be appreciated!


Solution

  • The last entry in the JSON at the URL looks different than the other ones: .

    {
      "-MxpO80SMxlqxMs6Q2-O" : {
        "description" : "is this long enough for you",
        "imageUrl" : "https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Cast-Iron-Pan.jpg/1024px-Cast-Iron-Pan.jpg",
        "isFavorite" : true,
        "price" : 420.99,
        "title" : "pan"
      },
      "-MxxqC8KwLPlgsmWBITe" : {
        "description" : "this is a test long one",
        "imageUrl" : "https://live.staticflickr.com/4043/4438260868_cc79b3369d_z.jpg",
        "isFavorite" : true,
        "price" : 12.0,
        "title" : "Yellow scarf"
      },
      "-MySBTTTKRTj4jXzAlhA" : {
        "amount" : 12.0,
        "dateTime" : "2022-03-18T15:22:46.740475",
        "products" : [ {
          "id" : "2022-03-18 15:22:43.791990",
          "price" : 12.0,
          "quantity" : 1,
          "title" : "Yellow scarf"
        } ]
      }
    }
    

    While Firebase can handle schemaless data, your code expect each child node to have certain properties and that -MySBTTTKRTj4jXzAlhA node doesn't have a id, title, description, imageUrl, or any of the other properties you're trying to read.