Eduardo Vasconcelos
Eduardo Vasconcelos

Reputation: 15

Firebase List in flutter

I implemented a search list with consultation to firebase. Initially, all registered users appear on the screen and when I click on one of the users, the app shows another screen with all the data for that user. When you start typing in the search field, only users with respect to the text entered appear.

However, a problem arose: when filtering a customer, only it appears on the screen and when I click to open the customer's information, the app shows the information of the first user in the general list (without taking into account the filter).

I believe that this happens due to the index, which looks at the position of the document in the firebase.

How to fix this? Thank you!

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

Upvotes: 0

Views: 334

Answers (2)

Eduardo Vasconcelos
Eduardo Vasconcelos

Reputation: 15

<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>

Hey! Unfortunately it didn't work, look what keeps happening.

I think this is because of the index I send as a parameter, which does not understand that the values have been filtered:

onTap: ()=> {
                       //print(data.documentID),
                       _navegarParaPerfil(context, items[index]),
                       }

void _navegarParaPerfil(BuildContext context, Paciente paciente) async{
    await Navigator.push(context,
     MaterialPageRoute(builder: (context) => TelaPaciente(paciente)),
     );
  }

Ideally, it would be validated by documentID instead of this index, but I was unable to change it

Upvotes: 0

Balasubramani Sundaram
Balasubramani Sundaram

Reputation: 1290

filtering

Step 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}';
}

Step 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);
    }
  }
}

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

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

        ],
      ),
    );
  }
}

Upvotes: 1

Related Questions