firebase - 将资产列表上传到 Firebase 存储并获取字符串列表 Flutter
问题描述
我有个问题。
所以我试图将多张图片上传到 Firebase 存储中,这些图片通过MultiImage选择器进入手机内存,该选择器仅将数据保存到 List < Asset > 中,这里的代码:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:multi_image_picker2/multi_image_picker2.dart';
import 'package:provider/provider.dart';
import '../widgets/bottom_navigation_bar.dart';
import '../providers/selling.dart';
//Property Features Screens
import '../screens/land_lot_size_features.dart';
import '../screens/condo_property_details_features.dart';
import '../screens/townhose_property_detais_features.dart';
import '../screens/home_property_details_features.dart';
import '../screens/selling_bathrooms.dart';
//Next Page Pricing
import '../screens/pricing_property.dart';
class MultipleImageDemo extends StatefulWidget {
static const routeName = '/multi-picker';
@override
_MultipleImageDemoState createState() => _MultipleImageDemoState();
}
class _MultipleImageDemoState extends State<MultipleImageDemo> {
List<Asset> images = <Asset>[];
double screenWidth = 0;
bool isLoading = false;
@override
void initState() {
setState(() {
isLoading = true;
});
images = Provider.of<Selling>(context, listen: false).images;
setState(() {
isLoading = true;
});
super.initState();
}
Future<void> loadAssets() async {
List<Asset> resultList = <Asset>[];
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 12,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Roof Deck",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
} on Exception catch (e) {
//String error = e.toString();
print(e);
}
if (!mounted) return;
setState(() {
images = resultList;
});
}
deleteImage(index) {
images.removeAt(index);
setState(() {});
}
@override
Widget build(BuildContext context) {
final topData = Provider.of<Selling>(context);
final typeOfProperty = topData.menu;
screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: SafeArea(
child: Stack(
children: [
// SizedBox(
// height: 1,
// ),
// Positioned(
// top: 0,
// left: 0,
// right: 0,
// child: Container(
// width: screenWidth,
// padding: const EdgeInsets.all(15),
// margin: const EdgeInsets.all(15),
// child: LinearPercentIndicator(
// width: screenWidth / 1.2,
// lineHeight: 8.0,
// percent: 0.50,
// progressColor: Colors.deepPurple[900],
// ),
// ),
// ),
Container(
// width: screenWidth,
// padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
// margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
// padding: const EdgeInsets.only(
// top: 5,
// left: 15,
// right: 15,
// ),
// margin: const EdgeInsets.only(
// top: 5,
// left: 15,
// right: 15,
// ),
child: Column(
children: [
Center(
child: Text(
'Photos',
style: TextStyle(fontSize: 25),
),
),
Divider(
color: Colors.grey,
thickness: 2.00,
),
SizedBox(
height: 5,
),
],
),
),
),
// SliverToBoxAdapter(
// child: Padding(
// padding: const EdgeInsets.only(
// left: 15.0, right: 15.0, bottom: 5.0),
// child: Text(
// 'Homes are 30% more likely to sell with high quality photos.',
// style: TextStyle(
// color: Colors.grey,
// fontSize: 18.00,
// ),
// ),
// ),
// ),
// SliverToBoxAdapter(
// child: Padding(
// padding: const EdgeInsets.only(
// left: 15.0, right: 15.0, bottom: 20.0),
// child: Text(
// 'You can only upload 12 pictures, if you need to remove a picture just tap on it.',
// style: TextStyle(
// color: Colors.grey,
// fontSize: 18.00,
// ),
// ),
// ),
// ),
SliverPadding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return index == images.length
? Center(
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(5),
border: Border.all(
color: Colors.grey, width: 1.0),
),
child: Container(
margin: const EdgeInsets.all(16.0),
padding: const EdgeInsets.all(8.0),
height: 100,
width: 100,
child: IconButton(
icon: Icon(
Icons.add, //add_a_photo,
size: 50.00,
color: Colors.white,
),
onPressed: () {
if (images.length < 12) {
loadAssets();
} else {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(
'Max Number of Pictures'),
content: Text(
'You reached the maximum number of pictures that can be uploaded (12 pictures)'),
actions: [
TextButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
),
],
),
);
}
},
),
),
),
)
: GestureDetector(
onTap: () {
deleteImage(index);
},
child: Container(
margin: const EdgeInsets.all(3),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: AssetThumb(
asset: images[index],
width: 300,
height: 300,
),
),
),
);
},
childCount: images.length + 1,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
),
),
],
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: Text(
'Previous',
style: TextStyle(fontSize: 22),
),
onPressed: () {
switch (typeOfProperty) {
case 0:
{
Navigator.pushNamed(
context, PropertyBathrooms.routeName);
}
break;
case 1:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
LandSizeFeatures()),
);
}
break;
case 2:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
TownhousePropertyDetails()),
);
}
break;
case 3:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
CondoPropertyDetails()),
);
}
break;
case 4:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
HomePropertyDetails()),
);
}
break;
}
// Navigator.pushNamed(
// context, PropertyBathrooms.routeName);
},
),
TextButton(
child: Text(
'Next',
style: TextStyle(fontSize: 22),
),
onPressed: () {
Provider.of<Selling>(context, listen: false)
.getImages(images);
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) => PricingProperty()),
);
//Navigator.pushNamed(context, PropertySize.routeName);
},
),
],
),
),
),
],
),
),
bottomNavigationBar: BottomNavBar(2),
);
}
}
一旦我们移动到不同的屏幕,我将该列表保存到 Provider 以使其在任何地方可用:
//***Property Images***/
List<Asset> _images = <Asset>[];
//Images Getter
List<Asset> get images {
return _images;
}
//Filling the Data Function
void getImages(List<Asset> images) {
_images = images;
notifyListeners();
}
//*** END OF IMAGES ***//
上面的代码是我在图像提供程序中填充图像的方式。
现在所有这些都有效,但问题是现在我希望将该列表中的所有图像上传到 Firebase 存储并返回带有图片查看 URL (DownloadURL) 的字符串列表。
我可以通过在 1 by 1 的情况下执行此操作并发送文件而不是像以下代码一样的资产列表来做到这一点:
final ref = FirebaseStorage.instance
.ref()
.child('user_images')
.child(authResult.user.uid + '.jpg');
await ref.putFile(image);
final url = await ref.getDownloadURL();
但是有没有办法一次完成所有这些操作,而不是一个一个地完成并检索下载 URL 的字符串列表?
我的最终目标是能够将这些图像存储在 Firebase 存储中,并将这些图像的 url 数组保存到 Firestore。
在我的简历中,我的问题是我没有上传文件或文件列表,而是上传资产列表,它是一个列表而不是单个列表。
谢谢你和亲切的问候。
解决方案
如果有人来这里寻求答案,我找到了:
- 首先,我将 List < File > 添加到我的 Multi Image Picker 并添加了此代码(resultList 是资产数组)。
我添加包flutter_absolute_path: ^1.0.6并得到以下代码:
resultList.forEach((imageAsset) async {
final filePath =
await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
File tempFile = File(filePath);
if (tempFile.existsSync()) {
fileImageArray.add(tempFile);
}
});
有了它,我将文件数组保存到我的 Provider 中。然后我创建了一个函数来上传到 Firebase 存储:
Future<void> uploadImages(String id) async {
int i = 0;
for (File imageFile in imageFiles) {
try {
var ref = FirebaseStorage.instance
.ref()
.child('ListingImages')
.child(id)
.child(i.toString() + '.jpg');
await ref.putFile(imageFile);
var url = await ref.getDownloadURL();
_imagesUrl.add(url);
i++;
} catch (err) {
print(err);
}
}
notifyListeners();
print(_imagesUrl);
}
允许我遍历每个上传的文件并将下载 URL 保存在字符串数组中。
希望这对你有帮助,伙计们。
推荐阅读
- javascript - 使用tablesorter通过选中的复选框对表格进行排序
- ios - 如何在点击时替换 SKSpriteNode 的图像
- swift - 函数设计为每 15 次单击执行一次,但始终在第一次单击时执行
- android - 将窗口 SystemUiVisibility 设置为 SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 时,全屏 DrawerLayouts 如何影响将片段添加到后台堆栈?
- spring - Spring 如何知道将返回对象转换为 JSON 而不是 XML 或任何其他格式?
- android - Android Maps,如何检查滚动长度
- swift - 从 CV2 单击返回时不要重新加载 VC1 - Swift
- excel - 将 Power BI Desktop 连接到 .odc 文件
- c# - 属性总是不可变的吗?
- ios - 将当前视图控制器添加到 navigationControllerStack