【问题标题】:Add data instead of overwriting it添加数据而不是覆盖它
【发布时间】:2021-06-30 15:48:59
【问题描述】:

当我使用弹出 AddPlanScreen 向小部件添加注释时,它会覆盖文档而不是添加它。注册、记录和设置数据正常工作。

我尝试做的事情:

  1. 使用 FirebaseFirestore.instance.runTransaction,但在向地图添加数据时,我无法对字符串使用 + 运算符。
  2. set(..., SetOptions(merge:true))
  3. 更新方法 我是否必须尝试创建一个新地图并在那里添加数据?我是编程新手,如果有任何建议,我将不胜感激。

这是我用来设置和获取数据的方法


import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class MyProvider extends ChangeNotifier {
  Map<String, dynamic> _names = {};

  String name(String key) => _names[key];

  void setName(String key, String newString) {
    _names[key] = newString;
    var firebaseUser = FirebaseAuth.instance.currentUser;
    FirebaseFirestore.instance
        .collection('Notes')
        .doc(firebaseUser.uid)
        .set(_names);
  }


  void fetchData() {
    var firebaseUser = FirebaseAuth.instance.currentUser;
    FirebaseFirestore.instance
        .collection('Notes')
        .doc(firebaseUser.uid)
        .get()
        .then((DocumentSnapshot documentSnapshot) {
      if (documentSnapshot.exists) {
        var data = documentSnapshot.data();
        _names = data;
      } else {
        print('The document does not exist on the database');
      }
    });
  }
}

这是我显示所有笔记的规划器屏幕


import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:my_planner_app/widgets/my_provider.dart';
import 'file:///C:/Users/krisk/AndroidStudioProjects/planner_app/lib/widgets/weekday_card.dart';
import 'package:provider/provider.dart';

class PlannerScreen extends StatefulWidget {
  static const String id = 'planner_screen';

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

class _PlannerScreenState extends State<PlannerScreen> {

  Widget build(BuildContext context) {
    Provider.of<MyProvider>(context, listen: false)
        .fetchData();
    var size = MediaQuery.of(context).size;

    final double itemHeight = (size.height - 24) / 2;
    final double itemWidth = size.width / 2;
    return Scaffold(
      backgroundColor: Color(0xFFcf9e9f),
      body: Container(
        child: GridView(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            childAspectRatio: (itemWidth / itemHeight),
          ),
          children: <Widget>[
            WeekDayCard(
              text: '',
            ),
            WeekDayCard(text: 'Monday' ),
            WeekDayCard(text: 'Tuesday'),
            WeekDayCard(text: 'Wednesday'),
            WeekDayCard(text: 'Thursday'),
            WeekDayCard(text: 'Friday'),
            WeekDayCard(text: 'Saturday'),
            WeekDayCard(text: 'Sunday'),
            WeekDayCard(text: 'Notes'),
          ],
        ),
      ),
    );
  }
}

这是关联的 WeekDayCard 小部件


import 'package:flutter/material.dart';
import 'package:my_planner_app/screens/addPlan_screen.dart';
import 'package:provider/provider.dart';
import 'package:my_planner_app/widgets/my_provider.dart';

class WeekDayCard extends StatefulWidget {
  WeekDayCard({@required this.text, this.name});
  final String name;
  final String text;

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

class _WeekDayCardState extends State<WeekDayCard> {
  @override


  Widget build(BuildContext context) {
    return Consumer<MyProvider>(builder: (context, myProvider, child) {
      return Card(
        color: Color(0xFFFEEFCD),
        elevation: 10,
        child: Column(
          children: [
            Text(widget.text),
            Text(Provider.of<MyProvider>(context).name(widget.text) ?? ''
    ),
            Expanded(
              child: InkWell(
                onTap: () {
                  showModalBottomSheet(
                    backgroundColor: Color(0xFFFEEFCD),
                    context: context,
                    builder: (context) => AddPlanScreen(weekdayName: widget.text),
                  );
                },
              ),
            ),
          ],
        ),
      );
    });
  }
}

这是关联的 AddPlanScreen


import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:my_planner_app/widgets/my_provider.dart';

class AddPlanScreen extends StatefulWidget {
  final String weekdayName;
  const AddPlanScreen({Key key, this.weekdayName}) : super(key: key);

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

class _AddPlanScreenState extends State<AddPlanScreen> {
  String name;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: TextFormField(
            onChanged: (text) {
              name = text;
            },
            decoration: InputDecoration(
              border: InputBorder.none,
            ),
            minLines: 10,
            maxLines: 30,
            autocorrect: false,
          ),
        ),
        FlatButton(
          onPressed: () {
            Provider.of<MyProvider>(context, listen: false)
                .setName(widget.weekdayName, name);
            Navigator.pop(context);
          },
          color: Colors.blue,
        ),
      ],
    );
  }
}

【问题讨论】:

    标签: database function flutter dart google-cloud-firestore


    【解决方案1】:
    • 只有当你是第一次创建一个文档并且你想给它一个指定的ID(不是由firebase随机生成的)时,你才应该使用set。或者,第二个用途是当您想故意改写现有数据时。

    • 当你想更新一个文档或其中的单个值\条目时,你只需使用:collection('yourCollection').doc('yourDocID').update({"nameOfnewField": "new data"})

    此更新方法不会覆盖您现有的文档,它只会添加一个名为"nameOfnewField" 的新字段,或者如果该字段已经存在,它只会覆盖它。

    即,如果 nameOfnewFieldfalse 的值,当您更新它时,使用 .update({"nameOfnewField": "true"}),它会变为 true,但文档的其余部分不会更改。

    【讨论】:

      猜你喜欢
      • 2018-12-13
      • 2018-07-15
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      相关资源
      最近更新 更多