简体   繁体   English

使用数据表时如何更新 Firebase 中的字段?

[英]How to update a field in Firebase when using a datatable?

How can I update a specific field in my Datatable .如何更新Datatable中的特定字段。 I am using this package: https://pub.dev/packages/responsive_table我正在使用这个包: https ://pub.dev/packages/responsive_table

When I tap on one item in my Datatable it opens a Dialog where I have my TextController and a ElevatedButton for updating my values.当我点击数据表中的一项时,它会打开一个Dialog ,其中有我TextController Datatable一个用于更新我的值的ElevatedButton All that seems to work, I click on one item, the right name of that item is stored in my TextController .所有这一切似乎都有效,我单击一个项目,该项目的正确名称存储在我的TextController中。 But when I press my button, it's updating some random item in my Firebase and not the value that i clicked in the first place.但是当我按下按钮时,它会更新我的Firebase中的一些随机项目,而不是我首先单击的值。

Here is my code:这是我的代码:

class _UsersPageState extends State<UsersPage> {

 
  var nameController = TextEditingController();


  @override
  Widget build(BuildContext context) {
    final UserTableProvider usertablesProvider = Provider.of<UserTableProvider>(context);
    return SingleChildScrollView(
        child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.max,
            children: [
              Container(
                margin: EdgeInsets.all(10),
                padding: EdgeInsets.all(0),
                constraints: BoxConstraints(
                  maxHeight: 700,
                ),
                child: Card(
                  elevation: 1,
                  shadowColor: Colors.black,
                  clipBehavior: Clip.none,
                  child: ResponsiveDatatable(
                    title: TextButton.icon(
                      onPressed: () => {
                        addUserDialog(context),
                      },
                      icon: Icon(Icons.add),
                      label: Text("Legg til bruker"),
                    ),
                    reponseScreenSizes: [ScreenSize.xs],
                    actions: [
                      if (usertablesProvider.isSearch)
                        Expanded(
                            child: TextField(
                              decoration: InputDecoration(
                                hintText: 'Søk på ansattnr..',
                                  prefixIcon: IconButton(
                                      icon: Icon(Icons.cancel),
                                      onPressed: () {
                                        setState(() {
                                          usertablesProvider.isSearch = false;
                                        });
                                      }),
                                  suffixIcon: IconButton(
                                      icon: Icon(Icons.search), onPressed: () {})),
                              onSubmitted: (value) {
                                usertablesProvider.filterData(value);
                              },
                            )),
                      if (!usertablesProvider.isSearch)
                        IconButton(
                            icon: Icon(Icons.search),
                            onPressed: () {
                              setState(() {
                                usertablesProvider.isSearch = true;
                              });
                            }),

                    ],
                    headers: usertablesProvider.userTableHeader,
                    source: usertablesProvider.source,
                    selecteds: usertablesProvider.selecteds,
                    showSelect: usertablesProvider.showSelect,
                    autoHeight: false,
                    onSort: (value) {
                      setState(() => usertablesProvider.isLoading = true);

                      setState(() {
                        usertablesProvider.sortColumn = value;
                        usertablesProvider.sortAscending = !usertablesProvider.sortAscending;
                        if (usertablesProvider.sortAscending) {
                          usertablesProvider.sourceFiltered.sort((a, b) =>
                              b["${usertablesProvider.sortColumn}"].compareTo(a["${usertablesProvider.sortColumn}"]));
                        } else {
                          usertablesProvider.sourceFiltered.sort((a, b) =>
                              a["${usertablesProvider.sortColumn}"].compareTo(b["${usertablesProvider.sortColumn}"]));
                        }
                        var _rangeTop = usertablesProvider.currentPerPage! < usertablesProvider.sourceFiltered.length
                            ? usertablesProvider.currentPerPage!
                            : usertablesProvider.sourceFiltered.length;
                        usertablesProvider.source = usertablesProvider.sourceFiltered.getRange(0, _rangeTop).toList();
                        usertablesProvider.searchKey = value;

                        usertablesProvider.isLoading = false;
                      });
                    },
                    expanded: usertablesProvider.expanded,
                    sortAscending: usertablesProvider.sortAscending,
                    sortColumn: usertablesProvider.sortColumn,
                    isLoading: usertablesProvider.isLoading,
                    onTabRow: (data){
                      
                      updateUserDialog(context);
                      print(data);

                      nameController.text = data['name'];
                      
                    },
                    onSelect: (value, item) {
                      print("$value  $item ");
                      if (value!) {
                        setState(() => usertablesProvider.selecteds.add(item));
                      } else {
                        setState(
                                () => usertablesProvider.selecteds.removeAt(usertablesProvider.selecteds.indexOf(item)));
                      }
                    },
                    onSelectAll: (value) {
                      if (value!) {
                        setState(() => usertablesProvider.selecteds =
                            usertablesProvider.source.map((entry) => entry).toList().cast());
                      } else {
                        setState(() => usertablesProvider.selecteds.clear());
                      }
                    },
                    footers: [
                      Container(
                        padding: EdgeInsets.symmetric(horizontal: 15),
                        child: Text("Rader per side:"),
                      ),
                      if (usertablesProvider.perPages.isNotEmpty)
                        Container(
                          padding: EdgeInsets.symmetric(horizontal: 15),
                          child: DropdownButton<int>(
                            value: usertablesProvider.currentPerPage,
                            items: usertablesProvider.perPages
                                .map((e) => DropdownMenuItem<int>(
                              child: Text("$e"),
                              value: e,
                            ))
                                .toList(),
                            onChanged: (dynamic value) {
                              setState(() {
                                usertablesProvider.currentPerPage = value;
                                usertablesProvider.currentPage = 1;
                                usertablesProvider.resetData();
                              });
                            },
                            isExpanded: false,
                          ),
                        ),
                      Container(
                        padding: EdgeInsets.symmetric(horizontal: 15),
                        child:
                        Text("${usertablesProvider.currentPage} - ${usertablesProvider.currentPerPage} of ${usertablesProvider.total}"),
                      ),
                      IconButton(
                        icon: Icon(
                          Icons.arrow_back_ios,
                          size: 16,
                        ),
                        onPressed: usertablesProvider.currentPage == 1
                            ? null
                            : () {
                          var _nextSet = usertablesProvider.currentPage - usertablesProvider.currentPerPage!;
                          setState(() {
                            usertablesProvider.currentPage = _nextSet > 1 ? _nextSet : 1;
                            usertablesProvider.resetData(start: usertablesProvider.currentPage - 1);
                          });
                        },
                        padding: EdgeInsets.symmetric(horizontal: 15),
                      ),
                      IconButton(
                        icon: Icon(Icons.arrow_forward_ios, size: 16),
                        onPressed: usertablesProvider.currentPage + usertablesProvider.currentPerPage! - 1 > usertablesProvider.total
                            ? null
                            : () {
                          var _nextSet = usertablesProvider.currentPage + usertablesProvider.currentPerPage!;

                          setState(() {
                            usertablesProvider.currentPage = _nextSet < usertablesProvider.total
                                ? _nextSet
                                : usertablesProvider.total - usertablesProvider.currentPerPage!;
                            usertablesProvider.resetData(start: _nextSet - 1);
                          });
                        },
                        padding: EdgeInsets.symmetric(horizontal: 15),
                      )
                    ],
                  ),
                ),
              ),
            ])
    );

  }

  updateUserDialog(BuildContext context){
    return showDialog(context: context, builder: (context) {
      return Dialog(
        child: Container(
          child: SizedBox(
            width: 600,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text('Endre bruker', style: TextStyle(
                    fontWeight: FontWeight.bold
                ),),
                SizedBox(
                  height: 10,
                ),
                TextField(
                  controller: nameController,
                  decoration: const InputDecoration(
                      labelText: 'Navn',
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.grey,
                        ),
                      ),
                      border: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.grey)
                      )
                  ),
             
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Colors.grey,
                        ),
                      ),
                      border: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.grey)
                      )
                  ),
                ),
               
                ElevatedButton(
                    onPressed: () async {
                      var name = nameController.text.trim();
              

                      FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;

                      FirebaseAuth auth = FirebaseAuth.instance;

                      User? user = auth.currentUser;



                      await firebaseFirestore.collection('users').doc(user!.uid).update({
                        'navn': name,
               

                      });


                      nameController.text = '';


                    },
                    child: const Text('Save')),
                const SizedBox(
                  height: 10,
                ),
              ],
            ),
          ),
        ),
      );
    });
  }    


    class UserTableProvider with ChangeNotifier {

  List<DatatableHeader> userTableHeader = [
    DatatableHeader(
        text: "Ansattnr",
        value: "empnumber",
        show: true,
        flex: 1,
        sortable: true,
        textAlign: TextAlign.left),
    DatatableHeader(
        text: "Navn",
        value: "name",
        show: true,
        flex: 6,
        sortable: true,
        textAlign: TextAlign.left),
    DatatableHeader(
        text: "Epost",
        value: "email",
        show: true,
        flex: 4,
        sortable: true,
        textAlign: TextAlign.left),
    DatatableHeader(
        text: "",
        value: "uid",
        show: false,
        sortable: true,
        textAlign: TextAlign.center),
    DatatableHeader(
        text: "Tlf",
        value: "tlfnumber",
        show: true,
        flex: 2,
        sortable: true,
        textAlign: TextAlign.left),
    DatatableHeader(
        text: "Eget verktøy",
        value: "owntool",
        show: false,
        sortable: true,
        textAlign: TextAlign.left),

  ];

  final List<int> perPages = [10, 20, 50, 100];
  int total = 100;
  int? currentPerPage = 10;
  int currentPage = 1;
  List<bool>? expanded;
  String? searchKey = "empnumber";

  bool isSearch = false;
  List<Map<String, dynamic>> sourceOriginal = [];
  List<Map<String, dynamic>> sourceFiltered = [];
  List<Map<String, dynamic>> source = [];
  List<Map<String, dynamic>> selecteds = [];
  // ignore: unused_field
  final String selectableKey = "id";

  String? sortColumn;
  bool sortAscending = true;
  bool isLoading = true;
  final bool showSelect = true;

  final UserServices _userServices = UserServices();
  List<UserModel> _users = <UserModel>[];
  List<UserModel> get users => _users;

  Future _loadFromFirebase() async {
    _users = await _userServices.getAllUsers();

  }

  List<Map<String, dynamic>> _getUsersData() {
    isLoading = true;
    List<Map<String, dynamic>> temps = [];
    var i = users.length;
    if (kDebugMode) {
      print(i);
    }
    // ignore: unused_local_variable
    for (UserModel userData in users) {
      if (kDebugMode) {
        print(userData.name);
      }
      if (kDebugMode) {
        print(userData.email);
      }
      temps.add({
        "empnumber": userData.empnumber,
        "email": userData.email,
        "name": userData.name,
        "uid": userData.uid,
        "owntool": userData.owntool,
        "tlfnumber": userData.tlfnumber,
      });
      i++;
    }


    return temps;
  }

  _initData() async {
    await _loadFromFirebase();
    mockPullData();
    notifyListeners();

  }

  mockPullData() async {
    expanded = List.generate(currentPerPage!, (index) => false);

    isLoading = true;
    Future.delayed(const Duration(seconds: 3)).then((value) {
      sourceOriginal.clear();
      sourceOriginal.addAll(_getUsersData());
      sourceFiltered = sourceOriginal;
      total = sourceFiltered.length;
      source = sourceFiltered.getRange(0, _users.length).toList();
      isLoading = false;
      notifyListeners();
    });
  }

  resetData({start: 0}) async {
    isLoading = true;
    var expandedLen =
    total - start < currentPerPage! ? total - start : currentPerPage;
    Future.delayed(const Duration(seconds: 0)).then((value) {
      expanded = List.generate(expandedLen as int, (index) => false);
      source.clear();
      source = sourceFiltered.getRange(start, start + expandedLen).toList();
      isLoading = false;
      notifyListeners();
    });
  }

  filterData(value) {
    isLoading = true;

    try {
      if (value == "" || value == null) {
        source = sourceOriginal;
      } else {
        sourceFiltered = sourceOriginal
            .where((data) => data[searchKey!]
            .toString()
            .toLowerCase()
            .contains(value.toString().toLowerCase()))
            .toList();
      }

      total = sourceFiltered.length;
      var _rangeTop = total < currentPerPage! ? total : currentPerPage!;
      expanded = List.generate(_rangeTop, (index) => false);
      source = sourceFiltered.getRange(0, _rangeTop).toList();
    } catch (e) {
      print(e);
    }
    isLoading = false;
    notifyListeners();
  }


  UserTableProvider.init() {
    _initData();
  }
}

The problem is the user id you are using to update the firestore document, the current user's id not the user id from the data.问题是您用于更新firestore文档的用户ID,当前用户的ID不是数据中的用户ID。

Please edit your updateUserDialog method, add the data as a parameter for the function.请编辑您的updateUserDialog方法,将数据添加为函数的参数。 Something like updateUserDialog(BuildContext context, Map<String, dynamic> data) .类似updateUserDialog(BuildContext context, Map<String, dynamic> data) This will avail the whole data Map within the method.这将利用方法中的整个数据映射。 This will expose the uid for you to use to update the right document.这将公开 uid 供您用于更新正确的文档。 You can then pass uid from the data Map as the doc as shown below.然后,您可以将数据映射中的 uid 作为文档传递,如下所示。

await firebaseFirestore.collection('users').doc(userId).update({
  'navn': name,
});

For the snippet above, the uid is stored in a variable userId .对于上面的代码片段, uid存储在变量userId中。

Below is the complete updated method you can work with.以下是您可以使用的完整更新方法。

updateUserDialog(BuildContext context, Map<String, dynamic> data) {
    nameController.text = data['name'];
    String userId = data['uid'].toString();

    return showDialog(
      context: context,
      builder: (context) {
        return Dialog(
          child: Container(
            child: SizedBox(
              width: 600,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text(
                    'Endre bruker',
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  TextField(
                    controller: nameController,
                    decoration: const InputDecoration(
                        labelText: 'Navn',
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(
                            color: Colors.grey,
                          ),
                        ),
                        border: OutlineInputBorder(
                            borderSide: BorderSide(color: Colors.grey))),
                  ),
                  ElevatedButton(
                      onPressed: () async {
                        var name = nameController.text.trim();

                        FirebaseFirestore firebaseFirestore =
                            FirebaseFirestore.instance;

                      
                        await firebaseFirestore
                            .collection('users')
                            .doc(userId)
                            .update({
                          'navn': name,
                        });

                        nameController.text = '';
                      },
                      child: const Text('Save')),
                  const SizedBox(
                    height: 10,
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }

You might as well update your onTabRow function to您不妨将onTabRow函数更新为

onTabRow: (data) {
   updateUserDialog(context, data);
},

That should solve your issue.那应该可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM