颤动中的 Firebase 列表

时间:2021-02-02 12:40:59

标签: list firebase flutter search google-cloud-firestore

我实施了一个搜索列表,并咨询了 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

2 个答案:

答案 0 :(得分:0)

filtering

第 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()}'),

        ],
      ),
    );
  }
}

答案 1 :(得分:0)

<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 而不是此索引进行验证,但我无法更改它