Firebase Firestore 原子事务用于在 Flutter 中将文档与 TextField 同步

阿布舍克·维什瓦卡玛

我是 firebase 和 firestore 的新手,在将 TextField 数据存储在 cloud firestore 中并对其执行事务时遇到问题,我怀疑我们是否可以执行更新事务,如果文档不存在,则它应该创建然后执行事务.. .

我想实现以下目标:

  1. 我想存储当前用户 uidemail“X”收集的文件内。

  2. 我想对“X”集合的“Y”(这里 Y 是 uid/email)文档执行交易更新,并且如果该用户的该文档不存在,它应该创建一个然后执行交易,然后如果用户在不按save按钮的情况下退出文本字段,然后它应该从 Firestore 中删除。

  3. 我想将用户的 uid、title、tag、desc 等作为该当前用户的 doc(docID应该是emailor user's uid)中的字段传递

到目前为止,我能够从 auth 类中获取用户并使用我当前的工作类访问它,initState()但我不知道如何获取该 uid/电子邮件并将其存储到“X”集合文档中

将数据传递给 firebase 的代码是,

 Future<void> postQ() async {
    FirebaseFirestore db = FirebaseFirestore.instance;
    CollectionReference question =
        FirebaseFirestore.instance.collection('question');
    DocumentReference cUser = question.doc(_currentUser.uid);
      // in the above line I tried to get currentuser uid but that also not working and below I want to pass title,etc... in the doc of that current user with fields title, tag, desc, users uid and email and docID should be the email or user's uid....
      await db.runTransaction((transaction) async {
      String title = title_Controller.text;
      String desc = desc_Controller.text;
      String tag = tag_Controller.text;
      DocumentReference qRef = db.collection('question').doc();
      DocumentSnapshot snapshot = await transaction.get(qRef);
      // int likesCount = snapshot.data['likes'];
      await transaction.update(qRef, {
        // 'authorId': _currentUser,
        'title': title,
        'desc': desc,
        'tag': tag,
      });
    });
  }
}

但是上面的代码将我抛出到消息下方,所以我如何在运行事务之前创建一个,并且该文档应该将当前用户 uid 和电子邮件作为字段之一。

无法在不存在的文档上运行事务

下面是从终端中的文本字段获取不断更新的工作代码,

class CreateQ extends StatefulWidget {
  final User user;
  CreateQ({Key? key, required this.user}) : super(key: key);

  @override
  State<CreateQ> createState() => _CreateQState();
}

class _CreateQState extends State<CreateQ> {
  final title_Controller = TextEditingController();
  final desc_Controller = TextEditingController();
  final tag_Controller = TextEditingController();
  @override
  void initState() {
    super.initState();
    _currentUser = widget.user;
    super.initState();
    // Start listening to changes.
    title_Controller.addListener(_latestTitle);
    desc_Controller.addListener(_latestDesc);
    tag_Controller.addListener(_latestTag);
  }

  // @override
  // void dispose() {
  // Clean up the controller when the widget is removed from the widget tree.
  // This also removes the latestvalue listener.
  // title_Controller.dispose();
  // super.dispose();
  // }

  void _latestTitle() {
    print('Title text field: ${title_Controller.text}');
  }

  void _latestDesc() {
    print('Desc text field: ${desc_Controller.text}');
  }

  void _latestTag() {
    print('Tag text field: ${tag_Controller.text}');
  }

  // ignore: unused_field
  late User _currentUser;
  

  UploadTask? task;
  File? file;

  @override
  Widget build(BuildContext context) {
 body: Container(
          padding: EdgeInsets.all(32),
          child: ListView(shrinkWrap: true, children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                TextField(
                  controller: title_Controller,
                  decoration: InputDecoration(
                      hintText: 'Your Title here',
                      counterText: '',
                      border: OutlineInputBorder()),
                  keyboardType: TextInputType.multiline,
                  maxLines: 1,
                  maxLength: 100,
                ),
                SizedBox(height: 8),
                TextField(
                  controller: desc_Controller,
                  decoration: InputDecoration(
                      hintText:
                          'Enter Your Description here... ',
                      border: OutlineInputBorder()),
                  keyboardType: TextInputType.multiline,
                  maxLines: 15,
                  maxLength: 10000,
                ),
                SizedBox(height: 8),
                TextField(
                  controller: tag_Controller,
                  decoration: InputDecoration(
                      hintText:
                          'Add up to 5 tags to describe what your question is about',
                      counterText: '',
                      border: OutlineInputBorder()),
                  keyboardType: TextInputType.text,
                  maxLines: 1,
                  maxLength: 100,
                ),  ));
  }

我尝试使用 set() 方法,但会引发错误 如果有人可以提供当前问题的工作示例,那将非常有帮助,谢谢...

Rutvik_110

如果文档不存在,则调用 update 不会创建文档。如果文档不存在,Set 将创建/更新文档。但是,您可以检查文档是否存在,然后根据需要使用 set 或 update。

 DocumentSnapshot snapshot = await transaction.get(qRef);
if(snapshot.exists){
  //run update/set operation
}else{
 // run set operation
}

无论您是否使用事务,设置和更新都将按照我上面提到的方式工作。如果对任何一个文档的任何设置/更新失败,事务使您能够撤消任何文档操作。

您可以通过此处了解 set 和 update 之间的差异。https://firebase.google.com/docs/firestore/manage-data/add-data

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章