You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter的InkWell点击事件中更新Firestore卡片数据?

实现Flutter中Firestore数据的更新功能

你已经搞定了数据获取、卡片展示和添加功能,现在要实现点击卡片内的更新图标修改对应Firestore文档的需求,咱们分三步来完成:

1. 添加Firestore数据更新方法

首先在你的crudMedthods类里补充更新逻辑,Firestore更新需要指定目标文档的ID,所以方法要接收文档ID和更新后的数据集:

Future<void> updateData(String docId, Map<String, dynamic> updatedData) async {
  if (isLoggedIn()) {
    await Firestore.instance
        .collection('dis')
        .document(docId)
        .updateData(updatedData)
        .catchError((e) {
      print(e);
    });
  } else {
    print('You need to be logged in');
  }
}

2. 创建预填充数据的更新弹窗

和添加弹窗逻辑类似,但要把当前卡片的现有数据填充到输入框里,方便用户直接修改:

Future<bool> updateDialog(BuildContext context, String docId, Map<String, dynamic> existingData) async {
  // 用现有数据初始化弹窗变量
  DateTime _updateDateTime = existingData['date'] as DateTime;
  String _updateTemsilci = existingData['temsilci'];
  String _updateSirano = existingData['sıra no'];
  String _updateTarih = existingData['tarih'];
  String _updateVerik = existingData['veri kaynağı'];

  return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      final _width = MediaQuery.of(context).size.width;
      return AlertDialog(
        title: Text('Temsilci Verisi Güncelleyin.', 
          style: GoogleFonts.montserrat(
            color: Colors.black54, 
            fontSize: 22, 
            fontWeight: FontWeight.w300
          ), 
          textAlign: TextAlign.center,
        ),
        content: SingleChildScrollView(
          child: Container(
            width: _width,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextField(
                  onTap: (){
                    showDatePicker(
                      context: context, 
                      initialDate: _updateDateTime, 
                      firstDate: DateTime(2000), 
                      lastDate: DateTime(2030)
                    ).then((date) {
                      setState(() {
                        _updateDateTime = date!;
                      });
                    });
                  },
                  decoration: InputDecoration(hintText: _updateDateTime.toString()),
                ),
                SizedBox(height: 5.0),
                TextField(
                  decoration: InputDecoration(hintText: 'Temsilci'),
                  controller: TextEditingController(text: _updateTemsilci),
                  onChanged: (value) => _updateTemsilci = value,
                ),
                SizedBox(height: 5.0),
                TextField(
                  decoration: InputDecoration(hintText: 'Sıra No'),
                  controller: TextEditingController(text: _updateSirano),
                  onChanged: (value) => _updateSirano = value,
                ),
                SizedBox(height: 5.0),
                TextField(
                  decoration: InputDecoration(hintText: 'Tarih'),
                  controller: TextEditingController(text: _updateTarih),
                  onChanged: (value) => _updateTarih = value,
                ),
                SizedBox(height: 5.0),
                TextField(
                  decoration: InputDecoration(hintText: 'Veri Kaynağı'),
                  controller: TextEditingController(text: _updateVerik),
                  onChanged: (value) => _updateVerik = value,
                ),
              ],
            ),
          ),
        ),
        actions: <Widget>[
          FlatButton(
            child: Text('İptal'),
            textColor: Colors.grey,
            onPressed: () => Navigator.of(context).pop(),
          ),
          FlatButton(
            child: Text('Güncelle'),
            textColor: Colors.blue,
            onPressed: () {
              Navigator.of(context).pop();
              // 调用更新方法提交修改
              crudObj.updateData(docId, {
                'date': _updateDateTime,
                'temsilci': _updateTemsilci,
                'sıra no': _updateSirano,
                'tarih': _updateTarih,
                'veri kaynağı': _updateVerik,
              }).then((result) {
                dialogTrigger(context); // 用你现有提示弹窗反馈结果
              }).catchError((e) => print(e));
            },
          )
        ],
      );
    });
}

3. 在卡片的InkWell中绑定更新弹窗

注意:要确保buildResultCard接收的是Firestore的DocumentSnapshot对象(这样才能拿到文档ID),修改卡片方法并在InkWell的点击事件里调用更新弹窗:

Widget buildResultCard(BuildContext context, DocumentSnapshot data) {
  return Card(
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
    elevation: 5,
    child: ExpansionCard(
      title: Column(
        children: [
          Row(
            children: [
              Padding(
                padding: EdgeInsets.fromLTRB(5, 0, 5, 1),
                child: Text(
                  data['isim'], 
                  style: GoogleFonts.montserrat(
                    color: Colors.blueGrey[700], 
                    fontSize: 20, 
                    fontWeight: FontWeight.w400
                  ), 
                  textAlign: TextAlign.center, 
                ),
              ),
              Spacer(), // 让更新图标靠右显示
              InkWell(
                child: Icon(Icons.update, color: Colors.blueGrey[700]),
                onTap: () {
                  // 传入文档ID和现有数据打开更新弹窗
                  updateDialog(context, data.documentID, data.data());
                },
              )
            ],
          ),
        ],
      ),
      // 保留你原有ExpansionCard的其他内容
    ),
  );
}

额外小提示

  • 构建列表时,要遍历QuerySnapshot的documents数组,把每个DocumentSnapshot传给buildResultCard,示例:
    FutureBuilder(
      future: SearchService().searchByName()[0],
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, index) {
              return buildResultCard(context, snapshot.data.documents[index]);
            },
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    )
    
  • 你原SearchService里的where('no')缺少查询条件,若要获取所有文档可以直接去掉这个语句,避免报错。

内容的提问来源于stack exchange,提问作者user14131906

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:47:43