Home > Software design >  "Unhandled Exception: type 'String' is not a subtype of type 'bool' "
"Unhandled Exception: type 'String' is not a subtype of type 'bool' "

Time:08-30

i just want to update my favorite status in Firebase when user is click on favorite icon.
all is done! but when i fetch data i got this error:
"Unhandled Exception: type 'String' is not a subtype of type 'bool' "
-isFavorite is a bool so what can i do?

here i got the error in this Function:

  Future<void> fetchAndSetProducts() async {
var url =
    'https://ecommerce-test-753ad-default-rtdb.firebaseio.com/products.json?auth=$authToken';
try {
  final response = await http.get(Uri.parse(url));
  final extractedData = json.decode(response.body) as Map<String, dynamic>;
  if (extractedData == {}) {
    return;
  }
  url =
      'https://ecommerce-test-753ad-default-rtdb.firebaseio.com/userFavorites/$userId.json?auth=$authToken';
  final favoriteResponse = await http.get(Uri.parse(url));
  final favoriteData = json.decode(favoriteResponse.body);
  final List<Product> loadedProduct = [];
  extractedData.forEach((key, value) {
    loadedProduct.add(
      Product(
        id: key,
        title: value['title'],
        price: value['price'],
        imageUrl: value['imageUrl'],
        description: value['description'],
        isFavorite:
            favoriteData == null? false : favoriteData[key] ?? false,
      ),
    );
  });
  _productItems = loadedProduct;
  notifyListeners();
} catch (e) {
  rethrow;
}
}

this is product Model class:

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

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


 void _setFavValue(bool newValue) {
  isFavorite = newValue;
  notifyListeners();
  }

Future<void> toggleFavoriteStatus(String authToken, String 
 userId) async {
  final oldStatus = isFavorite;
   isFavorite = !isFavorite;
  notifyListeners();
 final url =
     'https://ecommerce-test-753ad-default- 
rtdb.firebaseio.com/userFavorites/$userId/$id.json? 
auth=$authToken';
  try {
   final response = await http.put(
     Uri.parse(url),
    body: json.encode(isFavorite),
  );
  if (response.statusCode >= 400) {
    _setFavValue(oldStatus);
  }
} catch (error) {
  _setFavValue(oldStatus);
}
}

}

CodePudding user response:

The problem seems to be that the favoriteData[key] value that you get back from Firebase is in the form of a String, not a bool as you want it to be. Add these lines:

  extractedData.forEach((key, value) {

    // Two added lines:
    print('favoriteData[$key] is ${favoriteData[key]}');
    print('favoriteData[$key] is of type ${favoriteData[key].runtimeType}');

    loadedProduct.add(
      Product(
        id: key,
        title: value['title'],
        price: value['price'],
        imageUrl: value['imageUrl'],
        description: value['description'],
        isFavorite:
            favoriteData == null? false : favoriteData[key] ?? false,
      ),
    );

That will tell you exactly what is in that variable. If the output is:

favoriteData[some_key] is true
favoriteData[some_key] is of type String

then you know that you have accidentally uploaded the value in the form of a the String 'true' rather than the bool value true. Maybe you have uploaded '$isFavorite' instead of isFavorite or something...?

If you find that the value contains something else entirely, neither 'true' nor 'false' nor 'null', then you'll think of next steps from there!

  • Related