salmoa
salmoa

Reputation: 9

Stream provider is not filtering data according to where clause that I specified,

I have a stream provider that should return userData of the current logged in user. It should take information of user whose email is equal to current user.email.I guess the stream provider load data before the email of the current user is saved b'se it load information of all users `. So how should I make stream provider to wait until the email of the current user is saved . The function that load current user.

Future<void>loadLoggedUser() async{
  FirebaseAuth.instance
      .userChanges()
      .listen((User? user) {
    if (user == null) {
      print('User is currently signed out!');
    } else {
      email=user.email;
      userid=user.uid;
      print('User is signed in!');
    }
  });
  notifyListeners();
}

Stream provider for userData

    Stream<List<UserData>> get UserList {
  return _db.collection('users').where('email', isEqualTo: email)
      .snapshots()
      .map((snapshot) =>
      snapshot.docs
          .map((document) =>
          UserData.fromJson(document.data())).toList()
  );

}

Any help will be appreciated

Upvotes: 1

Views: 183

Answers (2)

Rajendra A Verma
Rajendra A Verma

Reputation: 423

You can also search like this if you want - Nested Streambuilder can help to achieve this sorting and searching problem. 1st StreamBuilder is of User and second for QuerySnapshot<Map<String, dynamic>>

StreamBuilder<User?>(
          stream: FirebaseAuth.instance.authStateChanges(),
          builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
            if (snapshot.hasData) {
              final String email = snapshot.data!.email;
              return StreamBuilder(
                stream: FirebaseFirestore.instance
                    .collection('users')
                    .where('email', isEqualTo: email)
                    .snapshots(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>
                        snapshot) {
                  if (snapshot.hasData) {
                    final list = snapshot.data!.docs
                        .map((document) => UserData.fromJson(document.data()))
                        .toList();
                    if (list.isNotEmpty) {
                      return ListView.builder(
                        shrinkWrap: true,
                        itemCount: list.length,
                        itemBuilder: (BuildContext context, int index) {
                          final userData = list[index];
                          return Text(userData
                              .name); // can print properties of userData model
                        },
                      );
                    }
                    return const Text("NO DATA AVAILABLE");
                  }
                  return const Text("Loading");
                },
              );
            }
            return const Center(
              child: Text("logged out"),
            );
          },
        ),

Upvotes: 1

Hrvoje Čukman
Hrvoje Čukman

Reputation: 447

I would suggest turning getter into a function and checking if user email is null or empty string (depending on how you initialise it in your code).

Stream<List<UserData>> getUserList(String? email) {
  if (email == null) throw Exception("Email is null");
  return _db
      .collection('users')
      .where('email', isEqualTo: email)
      .snapshots()
      .map((snapshot) => snapshot.docs
          .map((document) => UserData.fromJson(document.data()))
          .toList());
}

Upvotes: 0

Related Questions