【问题标题】:how add image to firestore in flutter image picker如何在颤振图像选择器中将图像添加到 Firestore
【发布时间】:2018-10-31 20:55:07
【问题描述】:

我想将照片添加到 Firestore。你能告诉我怎么做吗?

我正在使用图像选择器在我的 Flutter 应用中选择照片。

我的代码在下面

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,)
                  ],
                )
              ],
            ),
          ),
        ));
  }
}

【问题讨论】:

  • 下面没有代码。
  • 添加的代码请检查

标签: dart google-cloud-firestore flutter


【解决方案1】:

首先,从图库中获取图片

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);});
}

【讨论】:

    【解决方案2】:

    我建议将图像上传到云存储。 然后,您可以下载 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}');
      }
    }
    

    【讨论】:

      【解决方案3】:

      注意:以下代码使用了来自 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 是从存储中选择的文件的路径 此外,encode 方法需要 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,
          };
        }
      }
      

      要将encodedImageString 转换为Image,您可以使用以下代码

      Image.memory(base64.decode(encodedImageString))
      

      【讨论】:

        【解决方案4】:
          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 保存到您的收藏中。您可以选择自己的文档 ID,而不是 document(fileName)

        【讨论】:

        • 我把这个放在哪里,我想将文件发送到存储,然后将 url 保存到我的云火库
        【解决方案5】:

        我认为最好使用Cloud Storage 并只写它对 Cloud Firestore 的引用。 Cloud Firestore 不适用于保存图像、声音或电影等媒体。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-22
          • 2021-06-08
          • 2021-01-30
          • 1970-01-01
          • 2021-02-08
          • 2021-05-12
          • 2019-06-12
          • 2021-03-18
          相关资源
          最近更新 更多