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!