Reputation: 9
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
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
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