I'm using a cached network image to load in an image from firebase and if the image is URL is null it loads a circle avatar with an icon in it.
It works fine in the emulator but it always posts the error when image url is null:
I/flutter ( 6907): CacheManager: Failed to download file from with error:
I/flutter ( 6907): Invalid argument(s): No host specified in URI
when image url is not null:
I/flutter ( 6907): CacheManager: Failed to download file from with error:
I/flutter ( 6907): Invalid argument(s): No host specified in URI
══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI
When the exception was thrown, this was the stack:
#0 _HttpClient._openUrl (dart:_http/http_impl.dart:2662:9)
#1 _HttpClient.openUrl (dart:_http/http_impl.dart:2568:7)
#2 IOClient.send (package:http/src/io_client.dart:35:38)
#3 HttpFileService.get (package:flutter_cache_manager/src/web/file_service.dart:35:44)
#4 WebHelper._download (package:flutter_cache_manager/src/web/web_helper.dart:117:24)
#5 WebHelper._updateFile (package:flutter_cache_manager/src/web/web_helper.dart:99:28)
<asynchronous suspension>
#6 WebHelper._downloadOrAddToQueue (package:flutter_cache_manager/src/web/web_helper.dart:67:7)
<asynchronous suspension>
Image provider: CachedNetworkImageProvider("", scale: 1.0)
Image key: CachedNetworkImageProvider("", scale: 1.0):
CachedNetworkImageProvider("", scale: 1.0)
════════════════════════════════════════════════════════════════════════════════════════════════════
The UI shows exactly what it is suppose to though.
What can I do to fix this error from showing?
Here's the code:
class ProfilePicture extends GetView<UserController> {
const ProfilePicture({
Key? key,
this.enabled = false,
}) : super(key: key);
final bool enabled;
double get radius => enabled ? 40.0 : 30.0;
@override
Widget build(BuildContext context) {
return Obx(
() {
return Hero(
tag: 'profile_hero',
child: GestureDetector(
child: CachedNetworkImage(
imageUrl: controller.user?.photoURL ?? '',
placeholder: (context, url) => Container(),
errorWidget: (context, url, error) {
return Stack(
children: [
CircleAvatar(
radius: radius,
backgroundColor: Get.theme.brightness == Brightness.dark
? Colors.transparent
: Get.theme.scaffoldBackgroundColor,
child: Icon(Icons.person_outline_rounded,
size: radius * 1.5,
color: Get.theme.brightness == Brightness.dark
? Colors.white
: primaryColor),
),
Obx(
() => Visibility(
visible: controller.loading.value,
child: SizedBox(
height: radius * 2,
width: radius * 2,
child: const CircularProgressIndicator(),
),
),
),
],
);
},
imageBuilder: (_, imageProvider) {
return Stack(
children: [
CircleAvatar(
radius: radius,
backgroundImage: imageProvider,
),
Obx(() {
return Visibility(
visible: controller.loading.value,
child: SizedBox(
height: radius * 2,
width: radius * 2,
child: const CircularProgressIndicator(
strokeWidth: 5,
),
),
);
}),
],
);
},
),
onTap: () {
if (enabled) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
builder: (_) => const ImagePickerBottomModal(),
);
} else {
Get.to(
const ProfileScreen(),
routeName: AppRoutes.routeProfile,
curve: Curves.fastOutSlowIn,
transition: Transition.downToUp,
);
}
},
),
);
},
);
}
}
CodePudding user response:
Maybe you can do something like this. Create two CacheNetworkImage
based on your url. One is for null, another is for not null.
child: (controller.user?.photoURL == null) ?
CacheNetworkImage ( // with CircleAvatar ) : CacheNetworkImage(// with image path)
CodePudding user response:
You shouldn't be creating a CachedNetworkImage
at all if you don't have an image to load.
One way to do that:
@override
Widget build(BuildContext context) {
var photoURL = controller.user?.photoURL;
var fallback = Stack(
children: [
CircleAvatar(...)
],
);
return Obx(
() {
return Hero(
tag: 'profile_hero',
child: GestureDetector(
child: (photoURL == null)
? fallback
: CachedNetworkImage(
imageUrl: photoURL,
placeholder: (context, url) => Container(),
errorWidget: (context, url, error) => fallback,
...
A hacky alternative would be to just provide a non-routable URL which would be guaranteed to fail (e.g. https://0.0.0.0/
).