Reputation: 359
I want to fetch and cache user profile pictures from S3 into my flutter app.
First, when a user uploads a picture, my flask backend generates a random file name, stores the file in an S3 bucket (using boto3) and the name in the database.
To retrieve the picture I use presigned_urls:
s3client = boto3.client('s3', config=Config(signature_version='s3v4', region_name='eu-west-2'))
s3client.generate_presigned_url('get_object',Params={'Bucket': BUCKET,'Key': file_name_retrieved_from_db_for_user},ExpiresIn=120)
And then using a FutureBuilder I do the following:
FutureBuilder(
future: get_picture_url(user_id),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data==0) {
return Icon(Icons.account_circle, size: 110.0);
}
print(user_id);
print('this is the data fetched');
print(snapshot.data);
return CachedNetworkImage(
imageUrl: snapshot.data,
imageBuilder: (context, imageProvider) => Container(
width: 180.0,
height: 180.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover),
),
),
placeholder: (context, url) => ProfPicPlaceHolder(),
errorWidget: (context, url, error) => Icon(Icons.error),
);
} else {
return ProfPicPlaceHolder();
}
}
),
The problem is that each time the FutureBuilder calls the API to get the image's url, the URL is different due to different signature following the filename in the url, so the same image is loaded and cached again and again.
How can I access an image that is stored in S3 in flask using boto3 and then pass that url to cached network image in flutter? Is there any other way to cache an image in flutter from aws S3?
Upvotes: 2
Views: 2464
Reputation: 53
Adding to your solution, I create a simple function getAWSS3BaseImageUrl
String getAWSS3BaseImageUrl(String fullUrl) {
RegExp regExp = RegExp(r'(^[^?]+)');
Match? match = regExp.firstMatch(fullUrl);
return match?.group(1) ?? '';
}
And use it across the application to generate the cacheKey
values to use in both CachedNetworkImage
and CachedNetworkImageProvider
instances.
Examples
CachedNetworkImage(
imageUrl: yourURL,
cacheKey: getAWSS3BaseImageUrl(yourURL),
),
or
CachedNetworkImageProvider(
yourURL,
cacheKey: getAWSS3BaseImageUrl(yourURL),
),
Upvotes: 1
Reputation: 359
I implemented a solution. For those dealing with the same thing, use the property cacheKey of the CachedNetworkImage(). I used the filename (stored in user's table) as cacheKey. Also, I cache filename and file url in a hivebox which is updated regularly. My view reads data from the hivebox.
Upvotes: 2