颤动中的Firebase列表
Posted
技术标签:
【中文标题】颤动中的Firebase列表【英文标题】:Firebase List in flutter 【发布时间】:2021-05-06 15:31:42 【问题描述】:我实施了一个搜索列表,并咨询了 Firebase。最初,所有注册用户都出现在屏幕上,当我单击其中一个用户时,应用程序会显示另一个屏幕,其中包含该用户的所有数据。当您开始在搜索字段中输入内容时,只会显示与输入文本相关的用户。
但是,出现了一个问题:过滤客户时,只有它出现在屏幕上,当我点击打开客户信息时,应用程序会在总列表中显示第一个用户的信息(不考虑过滤器) )。
我相信这是由于索引,它查看文档在 firebase 中的位置。
如何解决这个问题?谢谢!
body: Column(
children: <Widget>[
SizedBox(
height: 5,
),
TextField(
controller: _procurarpaciente,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "Pesquisar paciente",prefixIcon: Icon(Icons.search)
),
onChanged: (val)
setState(()
nome = val;
);
,
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: (nome != "" && nome != null)
? Firestore.instance
.collection('pacientes')
.where("indexList", arrayContains: nome)
.snapshots()
: Firestore.instance.collection("pacientes").snapshots(),
builder: (context, snapshot)
switch(snapshot.connectionState)
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.error_outline),
Text("Usuário não encontrado")
],
),
);
default:
// List<DocumentSnapshot> documentos =
// snapshot.data.documents;
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index)
DocumentSnapshot data = snapshot.data.documents[index];
return ListTile(
title: Text(
data['nome'],
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 16,
),),
subtitle:Text(
"Quarto: $data['quarto']",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14,
),),
leading:CircleAvatar(
backgroundImage: NetworkImage(data['foto']),
),
onTap: ()=>
//print(data.documentID),
_navegarParaPerfil(context, items[index]),
);
,
);
),
)
],
),
void _navegarParaPerfil(BuildContext context, Paciente paciente) async
await Navigator.push(context,
MaterialPageRoute(builder: (context) => TelaPaciente(paciente)),
);
dsdsd
【问题讨论】:
_navegarParaPerfil(context, items[index]) --> items 表示 ? 当我按下所选用户时,我调用类 _navegarParaPerfil(导航到配置文件),将索引作为参数传递 @BalasubramaniSundaram 这个类,打开一个包含所选配置文件信息的屏幕 做完过滤,有没有刷新items collection @BalasubramaniSundaram 我尝试这样做,但即使在列表中显示正确的用户,当点击它时,过滤器也不会应用,并且总是打开列表中的第一个没有过滤器的用户跨度> 【参考方案1】:第 1 步:
class Employee
Employee(this.employeeID, this.employeeName, this.branch, this.designation, this.location,
this.salary,
this.reference);
double employeeID;
String employeeName;
String designation;
String branch;
String location;
double salary;
DocumentReference reference;
factory Employee.fromSnapshot(DocumentSnapshot snapshot)
Employee newEmployee = Employee.fromJson(snapshot.data());
newEmployee.reference = snapshot.reference;
return newEmployee;
factory Employee.fromJson(Map<String, dynamic> json) =>
_employeeFromJson(json);
Map<String, dynamic> toJson() => _employeeToJson(this);
@override
String toString() => 'employeeName $employeeName';
第 2 步:
class EmployeeRepository
List<Employee> employees = [];
final CollectionReference collection =
FirebaseFirestore.instance.collection('employees');
Stream<QuerySnapshot> getStream()
return collection.snapshots();
Future<DocumentReference> add(Employee employee)
var documentReference = collection.add(employee.toJson());
return documentReference;
update(Employee employee) async
collection.doc(employee.reference.id).update(employee.toJson());
delete(Employee employee) async
collection.doc(employee.reference.id).delete();
fromSnapShot(DocumentSnapshot snapshot) => Employee.fromSnapshot(snapshot);
Future<List<Employee>> buildData(
AsyncSnapshot snapshot, String filterKey) async
List<Employee> list = [];
List<Employee> filteredList = [];
/// Based on the user snapShot, you can convert into the List and return to
/// the futurebuilder
await Future.forEach(snapshot.data.docs, (element) async
list.add(Employee.fromSnapshot(element));
).then((value)
if (filterKey != null)
filteredList = list
.where((element) =>
element.employeeID.toString() == filterKey ||
element.employeeName == filterKey ||
element.designation == filterKey ||
element.branch == filterKey ||
element.location == filterKey ||
element.salary.toString() == filterKey)
.toList();
);
if (filteredList.isEmpty)
return Future<List<Employee>>.value(list);
else
return Future<List<Employee>>.value(filteredList);
第 3 步:
EmployeeRepository employeeRepository = EmployeeRepository();
TextEditingController textEditingController = TextEditingController();
String filteredText = '';
@override
Widget build(BuildContext context)
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('ListView'),
),
body: StreamBuilder(
stream: employeeRepository.getStream(),
builder: (context, snapShot)
if (snapShot.data == null ||
snapShot.connectionState == ConnectionState.waiting ||
snapShot.hasError ||
snapShot.data.docs.length == 0)
return Container(
child: Center(child: CircularProgressIndicator()),
);
else
return StatefulBuilder(builder: (context, innerSetState)
return FutureBuilder(
future: employeeRepository.buildData(
snapShot, filteredText),
builder: (context, futureSnapShot)
if (!futureSnapShot.hasData)
return Container(
child: Center(child: CircularProgressIndicator()),
);
else
return Column(
children: [
TextField(
controller: textEditingController,
decoration: InputDecoration(
icon: Icon(Icons.search),
hintText: 'Search here!'),
onSubmitted: (value)
innerSetState(()
filteredText = value;
);
,
onChanged: (value)
innerSetState(()
filteredText = value;
);
,
),
Container(
height: 400,
child: ListView.builder(
itemCount: futureSnapShot.data.length,
itemBuilder: (context, index)
final Employee employee =
futureSnapShot.data[index];
return ListTile(
title: Text(employee.employeeName),
trailing:
Text('Salary$employee.salary'),
subtitle: Text(employee.designation),
onTap: ()
print(employee.salary);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
EmployeeDetailsPage(
employee)));
,
);
,
),
),
],
);
);
);
,
)));
第 4 步:
class EmployeeDetailsPage extends StatelessWidget
final Employee employeeData;
const EmployeeDetailsPage(this.employeeData);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Employee Details'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text(employeeData.employeeName, style: TextStyle(fontSize: 30))),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text(employeeData.designation, style: TextStyle(fontSize: 20))),
),
Text('Salary $employeeData.salary.toString()'),
],
),
);
【讨论】:
嘿@BalasubramaniSundaram 不幸的是它没有用,你能看看我的答案吗?【参考方案2】:<blockquote class="imgur-embed-pub" lang="en" data-id="a/aqBaJ7N" data-context="false" ><a href="//imgur.com/a/aqBaJ7N"></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
嘿!不幸的是,它不起作用,看看发生了什么。
我认为这是因为我作为参数发送的索引,它不理解值已被过滤:
onTap: ()=>
//print(data.documentID),
_navegarParaPerfil(context, items[index]),
void _navegarParaPerfil(BuildContext context, Paciente paciente) async
await Navigator.push(context,
MaterialPageRoute(builder: (context) => TelaPaciente(paciente)),
);
理想情况下,它将通过 documentID 而不是此索引进行验证,但我无法更改它
【讨论】:
以上是关于颤动中的Firebase列表的主要内容,如果未能解决你的问题,请参考以下文章