End*_*mic 5 amazon-s3 amazon-web-services dart flutter dart-2
我的flutter应用程序使用Firebase作为后端,但是我需要在s3存储桶中存储媒体文件(照片和视频)。任务是将从图像选择器检索到的媒体上传到s3中,并获取该URL,然后将该URL作为字符串存储在我的Firebase数据库中。
问题是缺少飞镖2的aws库或api。我在酒吧里发现了3个,但其中2个与飞镖2和1不兼容。有没有人用飞镖2在颤抖中实现这一点?欢迎任何建议。谢谢。
我找到的包是(pub.dartlang.org):aws_client,aws_interop,amazon_s3
有几种方法可以做到这一点。一种方法是使用Signature V4 签名您的请求,然后将文件签名POST到S3。
首先,创建一个策略助手:
import 'dart:convert';
import 'package:amazon_cognito_identity_dart/sig_v4.dart';
class Policy {
String expiration;
String region;
String bucket;
String key;
String credential;
String datetime;
int maxFileSize;
Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
this.maxFileSize,
{this.region = 'us-east-1'});
factory Policy.fromS3PresignedPost(
String key,
String bucket,
String accessKeyId,
int expiryMinutes,
int maxFileSize, {
String region,
}) {
final datetime = SigV4.generateDatetime();
final expiration = (DateTime.now())
.add(Duration(minutes: expiryMinutes))
.toUtc()
.toString()
.split(' ')
.join('T');
final cred =
'$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
final p = Policy(key, bucket, datetime, expiration, cred, maxFileSize,
region: region);
return p;
}
String encode() {
final bytes = utf8.encode(toString());
return base64.encode(bytes);
}
@override
String toString() {
return '''
{ "expiration": "${this.expiration}",
"conditions": [
{"bucket": "${this.bucket}"},
["starts-with", "\$key", "${this.key}"],
{"acl": "public-read"},
["content-length-range", 1, ${this.maxFileSize}],
{"x-amz-credential": "${this.credential}"},
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-date": "${this.datetime}" }
]
}
''';
}
}
Run Code Online (Sandbox Code Playgroud)
然后,与保单助手签署您的请求,并通过进行上传http.MultipartRequest:
import 'dart:convert';
import 'package:amazon_cognito_identity_dart/sig_v4.dart';
class Policy {
String expiration;
String region;
String bucket;
String key;
String credential;
String datetime;
int maxFileSize;
Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
this.maxFileSize,
{this.region = 'us-east-1'});
factory Policy.fromS3PresignedPost(
String key,
String bucket,
String accessKeyId,
int expiryMinutes,
int maxFileSize, {
String region,
}) {
final datetime = SigV4.generateDatetime();
final expiration = (DateTime.now())
.add(Duration(minutes: expiryMinutes))
.toUtc()
.toString()
.split(' ')
.join('T');
final cred =
'$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
final p = Policy(key, bucket, datetime, expiration, cred, maxFileSize,
region: region);
return p;
}
String encode() {
final bytes = utf8.encode(toString());
return base64.encode(bytes);
}
@override
String toString() {
return '''
{ "expiration": "${this.expiration}",
"conditions": [
{"bucket": "${this.bucket}"},
["starts-with", "\$key", "${this.key}"],
{"acl": "public-read"},
["content-length-range", 1, ${this.maxFileSize}],
{"x-amz-credential": "${this.credential}"},
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-date": "${this.datetime}" }
]
}
''';
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,此方法要求您提供访问密钥和秘密密钥。如果您使用Cognito之类的服务,建议您获取一个临时访问密钥和秘密密钥。在此处找到使用临时访问的示例。
免责声明:我是Signature V4软件包的原始作者。
小智 5
您可以使用包amazon_s3_cognito将图像上传和删除到 amazon s3。
我是该插件的作者,我们在许多项目中成功使用了该插件。
import 'package:amazon_s3_cognito/amazon_s3_cognito.dart';
import 'package:amazon_s3_cognito/aws_region.dart';
String uploadedImageUrl = await AmazonS3Cognito.uploadImage(
_image.path, BUCKET_NAME, IDENTITY_POOL_ID);
//Use the below code to upload an image to amazon s3 server
//I advise using this method for image upload.
String uploadedImageUrl = await AmazonS3Cognito.upload(
_image.path,
BUCKET_NAME,
IDENTITY_POOL_ID,
IMAGE_NAME,
AwsRegion.US_EAST_1,
AwsRegion.AP_SOUTHEAST_1)
Run Code Online (Sandbox Code Playgroud)
_image.path = 要上传的图片的路径(flutter中的file.path方法)
IMAGE_NAME = 此图像使用您在此处指定的名称上传到 s3 服务器。
//use below code to delete an image
String result = AmazonS3Cognito.delete(
BUCKET_NAME,
IDENTITY_POOL_ID,
IMAGE_NAME,
AwsRegion.US_EAST_1,
AwsRegion.AP_SOUTHEAST_1)
Run Code Online (Sandbox Code Playgroud)
要获取图像,您可以使用cached_network_image包
。CachedNetworkImage可以直接使用或通过ImageProvider使用。
CachedNetworkImage(
imageUrl: "http://via.placeholder.com/350x150",
placeholder: (context, url) => new CircularProgressIndicator(),
errorWidget: (context, url, error) => new Icon(Icons.error),
),`enter code here`
Future<String> _getFilePath(Asset asset,ListingImage listingImage) async{
try {
if (!isUploadCancelled) {
// getting a directory path for saving
final directory = await getTemporaryDirectory();
String path = directory.path;
File file = File(path + "/temp_" + listingImage.index.toString() + "_"+DateTime.now().microsecondsSinceEpoch.toString());
listingImage.file = file;
file = await file.writeAsBytes( asset.imageData.buffer.asUint8List(asset.imageData.offsetInBytes, asset.imageData.lengthInBytes));
return file.path;
} else {
return null;
}
} catch(exceptioon) {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以使用Flutter Multipart,像这样
// open a bytestream
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
// get file length
var length = await _image.length();
// string to uri
var uri = Uri.parse(apiUrl);
// create multipart request
var request = new http.MultipartRequest("POST", uri);
NetworkUtils.addAuthHeaders(request);
// multipart that takes file
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(_image.path),
contentType: new MediaType("image", "jpg"));
// add file to multipart
request.files.add(multipartFile);
request.fields.addAll(body);
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3410 次 |
| 最近记录: |