首页 > 解决方案 > 无法在 Firestore 上保存正确的图片网址

问题描述

实际上,我正在按用户获取数据,将其保存在地图中并将此项添加到列表中。当用户在列表中添加了所有项目时,它按下浮动操作按钮将此列表添加到 Firestore 上的现有列表中。除 imageUrl 外,所有数据均已成功保存。列表中的第一项在 firestore 中具有 null imageUrl,但第二项分配了第一项的 imageUrl。序列还在继续……我不知道我错过了什么!我已经减去了大部分代码来具体说明。我认为问题是由被覆盖的变量itemImageUrl引起的。帮助!

这是代码:

class RetrieveShop extends StatefulWidget {
  String nameShop;String docId;


  RetrieveShop(this.nameShop,this.docId);

  @override
  _RetrieveShopState createState() => _RetrieveShopState();
}

class _RetrieveShopState extends State<RetrieveShop> {
  var result;

  bool isLoading = false;
  bool isLoadingNow = false;
  var _price = TextEditingController();
  var _itemName = TextEditingController();

/*  var _id = TextEditingController();
  var _category = TextEditingController();*/
  var _desc = TextEditingController();
  File _image;
  File _image2;
  String itemImageUrl;

  bool _showDg = false;
  bool condition = true;
  bool isPopular = false;
  bool savingAllDataToFirestore = false;
  List itemo=[];

  Future getImageFromGallery() async {
    var image = await ImagePicker()
        .getImage(source: ImageSource.gallery, imageQuality: 80);

    setState(() {
      _image = File(image.path);
      print('Image Path $_image');
    });
  }

  Future getImageFromCamera() async {
    var image = await ImagePicker().getImage(source: ImageSource.camera);

    setState(() {
      _image = File(image.path);
      print('Image Path $_image');
    });
  }

  Future uploadItemOfShop(BuildContext context) async {
    Reference ref = storage.ref().child(
        "${this.widget.nameShop}'s ${_itemName.text} Price ${_price.text}" +
            DateTime.now().toString());
    if (_image.toString() == '') {
      Flushbar(
        title: "Menu Item Image is empty",
        message: "Please Add some Image first",
        backgroundColor: Colors.red,
        boxShadows: [
          BoxShadow(
            color: Colors.red[800],
            offset: Offset(0.0, 2.0),
            blurRadius: 3.0,
          )
        ],
        duration: Duration(seconds: 3),
      )
        ..show(context);
    } else {
      setState(() {
        isLoadingNow=true;
      });
      debugPrint('wah');
      UploadTask uploadTask = ref.putFile(_image);
      uploadTask.then((res) async {
        itemImageUrl = await res.ref.getDownloadURL();
      }).then((value){
        setState(() {
          isLoadingNow=false;
        });
        debugPrint("Nullifing the Image object");
        _image=_image2; //Trying to null the file object after it is used so thinking that might 
                      //the problem is being caused here
      });

    }
  }


  Widget listTile(BuildContext context,String doc) {
    return !isLoadingNow?SingleChildScrollView(
      child: ListTile(
        title: Wrap(
          // mainAxisAlignment: MainAxisAlignment.start,
          direction: Axis.horizontal,
          children: [
            Text(
              "Enter details of Item",
              style: TextStyle(fontSize: 22, color: Colors.black87),
            ),
            Stack(
              children: [
                SizedBox(
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                  height: MediaQuery
                      .of(context)
                      .size
                      .height / 2.5,
                  child: (_image != null)
                      ? Image.file(
                    _image,
                    fit: BoxFit.cover,
                  )
                      : Image.network(
                    "https://images.unsplash.com/photo-1502164980785-f8aa41d53611?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
                    fit: BoxFit.fill,
                  ),
                ),
                Container(
                  alignment: Alignment.topLeft,
                  color: Colors.white38,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      IconButton(
                        icon: Icon(
                          Icons.add_a_photo,
                          size: 30.0,
                          color: Colors.black,
                        ),
                        onPressed: () {
                          getImageFromCamera();
                        },
                      ),
                      SizedBox(
                        width: 10,
                      ),
                      IconButton(
                        icon: Icon(
                          Icons.create_new_folder_rounded,
                          size: 30.0,
                          color: Colors.black,
                        ),
                        onPressed: () {
                          getImageFromGallery();
                        },
                      ),
                    ],
                  ),
                )
              ],
            ),
          ],
        ),
        subtitle: Column(
          children: [
            TextField(
              controller: _itemName,
              keyboardType: TextInputType.text,
              decoration: InputDecoration(
                  labelText: 'Enter Item name',
                  icon: Icon(Icons.fastfood),
                  alignLabelWithHint: true,
                  hintText: "Zinger Burger etc"),
              autofocus: true,
            ),
            TextField(
              controller: _price,
              autofocus: false,
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                  labelText: 'Enter Price',
                  icon: Icon(Icons.attach_money),
                  alignLabelWithHint: true,
                  hintText: "70 etc"),
            ),

            SwitchListTile(
              title: condition ? Text("Fresh") : Text("Used"),
              value: condition,
              onChanged: _onConditionChanged,
            ),
            SwitchListTile(
              title: isPopular ? Text("Popular") : Text("Not Popular"),
              value: isPopular,
              onChanged: _onPopularityChanged,
            ),
            TextField(
              autofocus: false,
              maxLength: 150,
              controller: _desc,
              keyboardType: TextInputType.multiline,
              maxLines: null,
              decoration: InputDecoration(
                  labelText: 'Enter Description',
                  icon: Icon(Icons.description),
                  alignLabelWithHint: true,
                  hintText:
                  "This item contains cheez and paneer with delicious mayonees etc.."),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                RaisedButton(
                    child: Text(
                      "Save",
                      style: TextStyle(color: Colors.white, fontSize: 16),
                    ),
                    color: Colors.red,
                    onPressed: () {

                      if(_image !=null){
                        int price=int.parse(_price.text);
                        String itemName=_itemName.text;
                        String itemDesc=_desc.text;
                        String categoryO=this.categoryToSave;
                        String imageUrl=this.itemImageUrl;
                    
                        uploadItemOfShop(context).then((value){
                          String idO=getRandomString(3);
                          var item = {
                            'itemName': itemName,
                            'itemPrice': price,
                            'itemDesc': itemDesc,
                            'category': categoryO,
                            'condition': condition,
                            'imageUrl': imageUrl,
                            'isPopular': this.isPopular,
                            'id': idO,
                          };

                          setState(() {
                            itemo.add(item);
                          });


                        });
                        setState(() {
                          _showDg = false;
                        });
                        _price.clear();
                        _desc.clear();
                        _itemName.clear();
                       /* imageUrl='';
                        itemImageUrl='';*/


                      }else{
                        Fluttertoast.showToast(msg: 'Please select some image first');
                      }


                    }
                    ),
              ],
            ),
          ],
        ),
        selectedTileColor: Colors.red.shade300,
      ),
    ):Padding(
      padding: const EdgeInsets.all(40.0),
      child: Center(
        child:CircularProgressIndicator()
      ),
    );
  }

  Widget myList(String nameOfButton2, {BuildContext buildContext}) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        StreamBuilder(
          stream: FirebaseFirestore.instance.collection('shops').where(
              'name', isEqualTo: this.widget.nameShop).snapshots(),
          builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if(snapshot.hasData){
              DocumentSnapshot list=snapshot.data.docs.single;
              return isLoadingNow
                  ? Center(child: CircularProgressIndicator())
                  : ListView.builder(
                itemCount: list.data()['menu'].length,
                physics: NeverScrollableScrollPhysics(),
                scrollDirection: Axis.vertical,
                shrinkWrap: true,
                itemBuilder: (context,int index){
                  return Card(
                    shadowColor: Colors.red,
                    //color: Colors.black,
                    elevation: 8.0,
                    //borderOnForeground: true,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(20.0),
                    ),
                    margin: EdgeInsets.only(
                        bottom: 10, right: 10),
                    child: ListTile(
                      leading:  CachedNetworkImage(
                        fit: BoxFit.cover,
                        //height: 100,
                        placeholderFadeInDuration:
                        Duration(seconds: 2),
                        fadeOutDuration: Duration(seconds: 2),
                        imageUrl: list
                            .data()['menu'][index]['imageUrl'],
                        progressIndicatorBuilder: (context, url,
                            downloadProgress) =>
                            Center(
                                child:
                                CircularProgressIndicator(
                                  value: downloadProgress.progress,
                                  color: kPrimaryColor,
                                )),
                        errorWidget: (context, url, error) =>
                            Icon(Icons.error),
                      ),
                      title:Text('Name: ${list.data()['menu'][index]['itemName']}'),

                      subtitle: Column(
                        crossAxisAlignment:CrossAxisAlignment.start,
                        children:[
                          Text(
                            "Price: ${list.data()['menu'][index]['itemPrice']} Rs",
                            style: TextStyle(
                                color: Colors.black54,
                                fontSize: 18),
                          ),
                          Text(
                            "Description: ${list.data()['menu'][index]['itemDesc']}",
                            style: TextStyle(
                                color: Colors.black87, fontSize: 20),
                          ),
                          list.data()['menu'][index]['condition']
                              ? Text("Condition: Fresh")
                              : Text("Condition: Used"),
                        ]
                      ),
                    ),
                  );
                },
              );
            }
            if(snapshot.hasError){
              return Text('Please try again');
            }
            return Center(
              child: CircularProgressIndicator(),
            );

          },
        ),

      ]
      ,
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("${this.widget.nameShop}"),
          centerTitle: false,
          actions: [
            IconButton(
                icon: Icon(Icons.add_comment),
                onPressed: () {
                  setState(() {
                    _showDg = !_showDg;
                  });
                })
          ],
        ),
        body: SafeArea(
          child: SingleChildScrollView(
            child: Column(
              children: [
                _showDg ? listTile(context,this.widget.docId) : Text(""),
                myList(this.widget.nameShop),
              ],
            ),
          ),
        ),
      floatingActionButton: FloatingActionButton(
        child: Text("Items ${itemo.length.toString()}"),
        onPressed: (){
          if(itemo.length==0){
            Fluttertoast.showToast(msg: 'Please add some items first');
          }else{
            FirebaseFirestore.instance.collection('shops').doc(this.widget.docId).update({
              "menu": FieldValue.arrayUnion(itemo),
            });
            setState(() {
              itemo=[];
            });
          }
        },
      ),
    );
  }
}

标签: flutterdartgoogle-cloud-firestore

解决方案


只是在上传任务对象之前缺少等待。


推荐阅读