如何更新一个字段在Firebase时使用一个数据表?



如何更新Datatable中的特定字段?我正在使用这个包:https://pub.dev/packages/responsive_table

当我点击我的Datatable中的一个项目时,它打开了一个Dialog,我有我的TextControllerElevatedButton来更新我的值。所有这些似乎都起作用了,我点击一个项目,该项目的正确名称存储在我的TextController中。但是当我按下按钮时,它会更新我的Firebase中的一些随机项目,而不是我首先点击的值。

下面是我的代码:
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();
}
}

问题是用于更新firestore文档的用户id,当前用户的id而不是数据中的用户id。

请编辑您的updateUserDialog方法,将数据添加为函数的参数。比如updateUserDialog(BuildContext context, Map<String, dynamic> data)。这将利用方法中的整个数据映射。这将公开uid,供您用于更新正确的文档。然后可以将数据映射中的uid作为文档传递,如下所示。

await firebaseFirestore.collection('users').doc(userId).update({
'navn': name,
});
对于上面的代码片段,uid存储在变量userId中。

下面是您可以使用的完整的更新方法。

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,
),
],
),
),
),
);
},
);
}

不妨将onTabRow函数更新为

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

这应该能解决你的问题。

最新更新