【发布时间】:2021-11-20 22:44:16
【问题描述】:
目前,我可以在 FirebaseStorage 中保存上传文件中的单个 url。 问题是当我有多个选择的文件 url 时,FirebaseFirestore 为 FirebaseStorage 上的每个上传文件创建多个具有不同 url 的文档。 我如何才能在 FirebaseFirestore 单个文档中添加所有选择的文件 url(如 List (url1: fileurl1, url2: fileurl2 ....)? 这是我的代码,谢谢!
import 'package:file_picker/file_picker.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:io';
class MobilePortraitFields extends StatefulWidget {
const MobilePortraitFields({Key? key}) : super(key: key);
@override
_MobilePortraitFieldsState createState() =>
_MobilePortraitFieldsState();
}
class _MobilePortraitFieldsState
extends State<MobilePortraitFields> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(child: _Body111()),
);
}
}
class _Body111 extends StatefulWidget {
@override
__Body111State createState() => __Body111State();
}
class __Body111State extends State<_Body111> {
final firebase_storage.FirebaseStorage _firebaseStorage = firebase_storage.FirebaseStorage.instance;
final TextEditingController descriptionController = TextEditingController();
final GlobalKey<FormState> _formKeyValue = GlobalKey<FormState>();
List<firebase_storage.UploadTask> uploadedTasks = [];
List<File> selectedFiles = [];
Future selectFiles() async {
try {
FilePickerResult? result = await FilePicker.platform
.pickFiles(allowMultiple: true, allowCompression: true);
if (result != null) {
selectedFiles.clear();
for (var selectedFile in result.files) {
File file = File(selectedFile.path ?? '');
selectedFiles.add(file);
}
} else {
// ignore: avoid_print
print("User has cancelled the selection");
}
} catch (e) {
// ignore: avoid_print
print(e);
}
}
uploadFilesToStorage(File file) {
firebase_storage.UploadTask task = _firebaseStorage
.ref()
.child("files/${DateTime.now().toString()}")
.putFile(file);
return task;
}
saveFilesUrlToFireStore(firebase_storage.UploadTask task) {
task.snapshotEvents.listen((snapShot) {
if (snapShot.state == firebase_storage.TaskState.success) {
snapShot.ref.getDownloadURL().then((value) => writeFilesUrlToFireStore(value));
}
});
}
writeFilesUrlToFireStore(value) {
Map<String, dynamic> issuesData = {
"description": descriptionController.text,
"location": 'Texas, USA',
"urls": value,
};
CollectionReference collectionReference =
FirebaseFirestore.instance.collection('issues');
collectionReference.add(issuesData);
}
addData() {
//Create button to add all in one document
if (_formKeyValue.currentState!.validate()) {
for (var file in selectedFiles) {
final firebase_storage.UploadTask task = uploadFilesToStorage(file);
saveFilesUrlToFireStore(task);
setState(() {
uploadedTasks.add(task);
});
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Was created successfully')));
Navigator.pop(context);
}
}
Widget _description() {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 35, 0, 0),
child: Container(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20)),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset: Offset(5, 5), // changes position of shadow
),
],
),
child: TextFormField(
controller: descriptionController,
decoration: InputDecoration(
hintText: 'Here you can describe ...',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20.0),borderSide: const BorderSide(color: Colors.grey),),
),
validator: (String? value) {
if (value!.isEmpty) {
return "Please provide description";
} else {
return null;
}
},
maxLines: 8,
),
),
);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Form(
autovalidateMode: AutovalidateMode.always,
key: _formKeyValue,
child: Column(
children: [
ListView(
shrinkWrap: true,
reverse: true,
padding: const EdgeInsets.symmetric(horizontal: 15.0),
children: <Widget>[
_description(),
const Padding(padding: EdgeInsets.fromLTRB(0, 10, 10, 0)),
ElevatedButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(const EdgeInsets.all(0)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)
),
backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
shadowColor: MaterialStateProperty.all<Color>(Colors.transparent)),
onPressed: addData,
child: Ink(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20)),
gradient: LinearGradient(
colors: [Color(0xFF21d39b), Color(0xFF0ac4ba)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
child: Container(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
constraints: const BoxConstraints(minWidth: 120, minHeight: 40),
alignment: Alignment.center,
child: const Center(
child: Text(
"Create",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
),
),
].reversed.toList(),
),
],
),
),
);
}
}
编辑:代码已更新。
【问题讨论】:
-
每次调用
collectionReference.add(...)都会创建一个新文档。如果您想要一个包含多个文件的文档,则需要确保在所有文件都已完全上传后只调用一次collectionReference.add(...)。 -
这并没有多大帮助。我已经将它们都更改为异步函数并放入等待,但我仍然有多个文档,它们之间只有区别,来自 FirebaseStorage 的 url。
标签: flutter dart google-cloud-firestore firebase-storage