Reputation: 25
I've been working on this problem for a while. There seems to be an error with the Flutter side of things, since I can access the file directly from the presigned URL that I generated on the backend. I've tried a number of different things, the latest being downloading the image using the http package and then attempting to display it, but I always get this error:
════════ Exception caught by image resource service ════════════════════════════ The following _Exception was thrown resolving an image frame: Exception: Codec failed to produce an image, possibly due to invalid image data.
For context, I've included the Go and Flutter code below:
Like I mentioned above, the Go portion of the code seems to work.
func FetchPresignedURL(c *gin.Context) {
sess := session.Must(session.NewSession(&aws.Config{
Credentials: credentials.NewStaticCredentials(os.Getenv("DO_SPACES_ACCESS_KEY"), os.Getenv("DO_SPACES_SECRET_KEY"), ""),
Endpoint: aws.String(os.Getenv("DO_SPACES_ENDPOINT")),
Region: aws.String(os.Getenv("DO_SPACES_REGION")),
}))
svc := s3.New(sess)
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(os.Getenv("DO_SPACES_BUCKET")),
Key: aws.String(c.Query("file_path")),
})
//Presign for an hour
urlStr, err := req.Presign(7 * 24 * time.Hour)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to generate presigned URL",
})
return
}
c.JSON(http.StatusOK, gin.H{
"url": urlStr,
})
}
There must be something in the way that I'm trying to use the image in Flutter that is causing this error:
Future<ImageProvider> loadImage(String url) async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
return MemoryImage(response.bodyBytes);
} else {
print('Failed to load image: HTTP status code ${response.statusCode}');
throw Exception('Failed to load image');
}
} catch (e) {
print('Failed to load image: $e');
throw Exception('Failed to load image');
}
}
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((_) async {
showLoading(context);
...
String? presignedURL = await HandleFetchPresignedURL(context, user.pic);
if (presignedURL == null) {
ShipErrorToUI(context, "Error loading profile picture");
} else {
try {
final imageProvider = await loadImage(presignedURL);
setState(() {
pic = imageProvider;
});
} catch (e) {
print('Failed to load image: $e');
}
}
print(
"${name} - ${intro} - ${dob} - ${pic} - ${selectedCountry} - ${selectedLocation}");
} else {
ShipErrorToUI(context, "There was an error fetching user data");
}
hideLoading(context);
});
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
...
SizedBox(height: 16.0),
Container(
child: pic != null ? Image(image: pic!) : Text('No image available'),
),
...
Upvotes: 1
Views: 77