我想将照片添加到firestore。你能告诉我怎么做吗?
我正在使用图片选择器在我的颤动应用程序中选择照片。
我的代码在
下面import 'package:flutter/material.dart';
import 'package:onlinecity/component/TextField/inputField.dart';
import 'package:onlinecity/component/Button/roundedButton.dart';
import 'package:onlinecity/component/Button/textButton.dart';
import 'style.dart';
import 'package:onlinecity/theme/style.dart';
import 'package:flutter/services.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:async';
import 'dart:io';
class AddOfferScreen extends StatefulWidget {
@override
AddOfferScreenState createState() => new AddOfferScreenState();
}
class AddOfferScreenState extends State<AddOfferScreen> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool _autovalidate = false;
String _productTitle;
String _category;
String _contactNumber;
Future<File> _imageFile;
void _onImageButtonPressed(ImageSource source) {
setState(() {
_imageFile = ImagePicker.pickImage(source: source);
});
}
_onPressed() {
print("button clicked");
}
void showInSnackBar(String value) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(value)));
}
bool _handleSubmitted() {
final FormState form = _formKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
void validateAndSubmit() async{
if (_handleSubmitted()){
try {
Firestore.instance.collection('todos').document().setData({"productTitle":_productTitle,"category":_category,"contactNumber":_contactNumber});
}
catch (e){
print('Error: $e');
}
}
}
void _showaddphoto(){
AlertDialog dialog = new AlertDialog(
actions: <Widget>[
new IconButton(icon: new Icon(Icons.camera_alt), onPressed: () => _onImageButtonPressed(ImageSource.camera),
tooltip: 'Take a Photo'),
new IconButton(icon: new Icon(Icons.sd_storage), onPressed: () => _onImageButtonPressed(ImageSource.gallery),
tooltip: 'Pick Image from gallery')
],
);
showDialog(context: context,child: dialog);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
Size screenSize = MediaQuery.of(context).size;
//print(context.widget.toString());
return new Scaffold(
key: _scaffoldKey,
body: new SingleChildScrollView(
child: new Container(
padding: new EdgeInsets.all(16.0),
decoration: new BoxDecoration(image: backgroundImage),
child: new Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new SizedBox(
height: screenSize.height / 2 + 20,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
"CREATE ACCOUNT",
textAlign: TextAlign.center,
style: headingStyle,
)
],
)),
new Column(
children: <Widget>[
new Form(
key: _formKey,
autovalidate: _autovalidate,
//onWillPop: _warnUserAboutInvalidData,
child: new Column(
children: <Widget>[
new FutureBuilder<File>(
future: _imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
return new Image.file(snapshot.data);
} else if (snapshot.error != null) {
return const Text('error picking image.');
} else {
return const Text('You have not yet picked an image.');
}
},
),
new RaisedButton.icon(onPressed: _showaddphoto, icon: new Icon(Icons.add_a_photo), label: new Text('Add Photo')),
new InputField(
hintText: "product title",
obscureText: false,
textInputType: TextInputType.text,
textStyle: textStyle,
textFieldColor: textFieldColor,
icon: Icons.person_outline,
iconColor: Colors.white,
bottomMargin: 20.0,
validateFunction: (value)=> value.isEmpty ? 'UserName can\'t be empty' : null,
onSaved: (value)=> _productTitle = value,
),
new InputField(
hintText: "Category",
obscureText: false,
textInputType: TextInputType.emailAddress,
textStyle: textStyle,
textFieldColor: textFieldColor,
icon: Icons.mail_outline,
iconColor: Colors.white,
bottomMargin: 20.0,
validateFunction: (value)=> value.isEmpty ? 'Email can\'t be empty' : null,
onSaved: (value)=> _category = value,
),
new InputField(
hintText: "Contact Number",
obscureText: true,
textInputType: TextInputType.text,
textStyle: textStyle,
textFieldColor: textFieldColor,
icon: Icons.lock_open,
iconColor: Colors.white,
bottomMargin: 40.0,
validateFunction: (value)=> value.isEmpty ? 'Contact number can\'t be empty' : null,
onSaved: (value)=> _contactNumber = value,
),
new RoundedButton(
buttonName: "Continue",
onTap: validateAndSubmit,
width: screenSize.width,
height: 50.0,
bottomMargin: 10.0,
borderWidth: 1.0)
],
)),
new TextButton(
buttonName: "Terms & Condition", onPressed: _onPressed,buttonTextStyle: buttonTextStyle,)
],
)
],
),
),
));
}
}
答案 0 :(得分:2)
import 'package:firebase_storage/firebase_storage.dart';
/////////
var fileName = "fileName.jpeg";
StorageUploadTask putFile =
storage.ref().child("folder/$fileName").putFile(_image);
putFile.future.catchError(onError);
UploadTaskSnapshot uploadSnapshot = await putFile.future;
print("image uploaded");
Map<String, dynamic> pictureData = new Map<String, dynamic>();
pictureData["url"] = uploadSnapshot.downloadUrl.toString();
DocumentReference collectionReference =
Firestore.instance.collection("collection").document(fileName);
await Firestore.instance.runTransaction((transaction) async {
await transaction.set(collectionReference, pictureData);
print("instance created");
}).catchError(onError);
这里,这会将文件存储到存储中,然后将downloadUrl保存到您的集合中。而不是document(fileName)
,您可以选择自己的文档ID。
答案 1 :(得分:1)
我认为最好使用Cloud Storage并仅写入其对Cloud Firestore的引用。 Cloud Firestore不用于保存图像,声音或电影等媒体。
答案 2 :(得分:0)
注意:以下代码使用了pub.dev中的ImagePicker包
要将图像存储在Firestore中,您可以将图像转换为字符串
首先导入以下软件包
import 'package:image_picker/image_picker.dart';
import 'dart:convert';
然后使用以下代码
使用ImagePicker类从存储中获取图像
ImagePicker picker = ImagePicker();
pickedFile = await picker.getImage(
source: ImageSource.gallery,
maxHeight: 200,
);
然后将图像转换为基于base64的字符串
String encodedImageString = base64.encode(File(pickedFile.path).readAsBytesSync().toList());
注意: pickedFile.path 是从存储中选择的文件的路径 另外,编码方法需要List,可以使用-> readAsBytesSync()。toList()
一旦图像中包含字符串,您可以按照以下步骤将其存储到firestore中
FirebaseFirestore.instance.collection('users').doc(uid).set(company.toDocument()), SetOptions(merge: true));
toDocument()是在我的模型类中定义的一种方法,用于在Map对象中转换对象,请参见下文
class Company extends Equatable {
final String id;
final String name;
final String logo;
Company({
this.id,
@required this.name,
@required this.logo,
});
Company copyWith({
String id,
String name,
String logo,
}) {
return Company(
id: id ?? this.id,
name: name ?? this.name,
logo: logo ?? this.logo,
);
}
static Company fromSnapshot(DocumentSnapshot snap) {
return Company(
id: snap.id,
name: snap.get('name'),
logo: snap.get('logo'),
);
}
Map<String, Object> toDocument() {
return {
'name': name,
'logo': logo,
};
}
}
要将编码的ImageString转换为图像,您可以使用以下代码
Image.memory(base64.decode(encodedImageString))
答案 3 :(得分:0)
我建议将图像上传到云存储。 然后,您可以下载该 url 并将该 url 上传到 firestore。
这是将图像上传到存储的代码。
Future uploadFiles(File file) async {
try {
await firebase_storage.FirebaseStorage.instance.ref('Images/image.png').putFile(file);
print("Successfully upload file ${i + 1}");
} on firebase_core.FirebaseException catch (e) {
print('error is ${e.message}');
}
}
答案 4 :(得分:0)
首先,从图库中获取图像
File? _image;
final _picker = ImagePicker();
var imgValue;
Future getImageFromGallery() async {
final pickedFile = await _picker.getImage(source: ImageSource.gallery);
final File image = File(pickedFile!.path);
// File image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
}
然后上传图片到firestore:
Future uploadImageToFirebase() async {
String fileName = basename(_image!.path);
FirebaseStorage firebaseStorageRef = FirebaseStorage.instance;
Reference ref =firebaseStorageRef.ref().child('upload/$fileName'+ DateTime.now().toString());
// FirebaseStorage.instance.ref().child('uploads/$fileName');
UploadTask uploadTask = ref.putFile(_image!);
uploadTask.then((res) {res.ref.getDownloadURL().then((value) => imgValue = value);});
}