Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
222 views
in Technique[技术] by (71.8m points)

flutter - How do I optionally upload images to my database/storage?

Here I want the user to be able to upload up to 5 images. But when one uploads less than 5 images it freezes the app and does not upload the document at all.

class ItemInput extends StatefulWidget {
  @override
  _ItemInputState createState() => _ItemInputState();
}

class _ItemInputState extends State<ItemInput> {
  final Firestore database = Firestore.instance;
  //CollectionReference products = Firestore.instance.collection('products');

  TextEditingController nameText = TextEditingController();
  TextEditingController priceText = TextEditingController();
  TextEditingController cellNoText = TextEditingController();
  TextEditingController addText = TextEditingController();
  TextEditingController detailText = TextEditingController();
  TextEditingController pic = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  File _image1;
  File _image2;
  File _image3;
  File _image4;
  File _image5;
  
  static const menuItems = <String>[
    'Car/????',
    'motorcycle/ ?????????',
    'electronics/?????????',
    'house/ ????',
    'household/????? ????',
    'mobile/??????',
    'Sellect Category/?????? ???',
  ];

  final List<DropdownMenuItem<String>> _dropDownMenuItems = menuItems
      .map((String value) => DropdownMenuItem<String>(
            value: value,
            child: Text(value),
          ))
      .toList();
  
  String _btnselected = "Sellect Category/?????? ???";

  Future getImage1() async {
    var firstImage = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image1 = firstImage;
    });
  }

  Future getImage2() async {
    var secondImage = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image2 = secondImage;
    });
  }

  Future getImage3() async {
    var thirdImage = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image3 = thirdImage;
    });
  }

  Future getImage4() async {
    var forthImage = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image4 = forthImage;
    });
  }

  Future getImage5() async {
    var fifthImage = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image5 = fifthImage;
    });
  }

  var imageUrl1;
  var imageUrl2;
  var imageUrl3;
  var imageUrl4;
  var imageUrl5;

  FirebaseStorage storage = FirebaseStorage.instance;

  uploadPic() async {
    StorageReference reference = storage.ref().child("images");
    StorageUploadTask uploadTask = reference.putFile(_image1);
    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    String url = await taskSnapshot.ref.getDownloadURL();
    imageUrl1 = url;
    return url;
  }

  /////2
  uploadPic2() async {
    StorageReference reference = storage.ref().child("images");
    StorageUploadTask uploadTask = reference.putFile(_image2);
    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    String url = await taskSnapshot.ref.getDownloadURL();
    imageUrl2 = url;
    return url;
  }

  ////3
  uploadPic3() async {
    
    StorageReference reference = storage.ref().child("images");
    StorageUploadTask uploadTask = reference.putFile(_image3);
    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    String url = await taskSnapshot.ref.getDownloadURL();
    imageUrl3 = url;
    return url;
  }

  ///4
  uploadPic4() async {
    StorageReference reference = storage.ref().child("images");
    StorageUploadTask uploadTask = reference.putFile(_image4);
    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    String url = await taskSnapshot.ref.getDownloadURL();
    imageUrl4 = url;
    return url;
  }

  ///5
  uploadPic5() async {
    StorageReference reference = storage.ref().child("images");
    StorageUploadTask uploadTask = reference.putFile(_image5);
    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    String url = await taskSnapshot.ref.getDownloadURL();
    imageUrl5 = url;
    return url;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Put AD'),
          centerTitle: true,
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(5.0),
            child: Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Form(
                  key: _formKey,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      TextFormField(
                        controller: nameText,
                        decoration: const InputDecoration(
                          icon: const Icon(Icons.directions_car),
                          hintText: 'Corolla, Mercedes...',
                          labelText: 'Item Name - ??? ???',
                        ),
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        controller: detailText,
                        decoration: const InputDecoration(
                          icon: const Icon(Icons.description),
                          hintText: 'Description - ??????',
                          labelText: 'Description - ??????',
                        ),
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        controller: priceText,
                        decoration: const InputDecoration(
                          icon: const Icon(Icons.attach_money),
                          hintText: 'Enter your item's price',
                          labelText: 'Price - ????',
                        ),
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        controller: cellNoText,
                        decoration: const InputDecoration(
                          icon: const Icon(Icons.call),
                          hintText: '0700-000-000',
                          labelText: 'Mobile Number -  ????? ????',
                        ),
                      ),
                      SizedBox(height: 10),
                      TextFormField(
                        controller: addText,
                        decoration: const InputDecoration(
                          icon: const Icon(Icons.location_city),
                          hintText: 'Enter Your Address',
                          labelText: 'Address - ????',
                        ),
                      ),
                      SizedBox(height: 30),
                      Padding(
                        padding: const EdgeInsets.all(5.0),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                            //////// dropdown start //////////
                            DropdownButton(
                              hint: Text('Sellect Category'),
                              value: _btnselected,
                              items: this._dropDownMenuItems,
                              onChanged: (String newvalue) {
                                setState(() {
                                  _btnselected = newvalue;
                                });
                              },
                            ),
                            ///////  dropdown end  //////
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                InkWell(
                                  onTap: () async {
                                    await getImage1();
                                  },
                                  child: Container(
                                      decoration: BoxDecoration(
                                          color: Colors.black26,
                                          borderRadius:
                                              BorderRadius.circular(10)),
                                      height: 60,
                                      width: 60,
                                      child: (_image1 == null)
                                          ? Icon(Icons.add_a_photo, size: 30)
                                          : Image.file(
                                              _image1,
                                              fit: BoxFit.cover,
                                            )
                                      ),
                                ),
                                SizedBox(width: 5),
                                InkWell(
                                  onTap: () async {
                                     await getImage2();
                                  },
                                  child: Container(
                                      height: 60,
                                      width: 60,
                                      decoration: BoxDecoration(
                                          color: Colors.black26,
                                          borderRadius:
                                              BorderRadius.circular(10)),
                                      child: (_image2 == null)
                                          ? Icon(Icons.add_a_photo, size: 30)
                                          : Image.file(
                                              _image2,
                                              fit: BoxFit.fill,
                                            )),
                                ),
                                SizedBox(width: 5),
                                InkWell(
                                  onTap: () async {
                                    await getImage3();
                                  },
                                  child: Container(
                                      height: 60,
                                      width: 60,
                                      decoration: BoxDecoration(
                                          color: Colors.black26,
                                          borderRadius:
                                              BorderRadius.circular(10)),
                                      child: (_image3 == null)
                                          ? Icon(Icons.add_a_photo, size: 30)
                                          : Image.file(
                                              _image3,
                                              fit: BoxFit.fill,
                                            )),
                                ),
                                SizedBox(width: 5),
                                InkWell(
                                  onTap: () async {
                                    await getImage4();
                                  },
                                  child: Container(
                                      height: 60,
                                      width: 60,
                                      decoration: BoxDecoration(
                                          color: Colors.black26,
                                          borderRadius:
                                      

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're forgetting await on the null check of each of the uploading functions. You're checking if the returned Future is null, not the value of the Future. Simply adding await to the beginning of each null check would solve the issue. Ex.

"image 1 Url": (await uploadPic() != null)
    ? await uploadPic()
    : "null",

However, for efficiency, you should handle the uploading logic outside of the add method of the database. Ex.

String image1 = (await uploadPic()) ?? 'null';
...
database.collection("car").add({
  ...
  "image 1 Url": image1,
  ...
});

As others have said in the comments there isn't a need for 5 different upload functions, but if you want to keep it that way, it should be fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...