Hello I am making a chat app in flutter with Firebase where you can search users by their username. I builded a Listview of all the users of my application with a
Provider.of<List<AppUserData>>(context)
for testing and it worked. Now I am trying to use this Stream Provider to provide users by their usernames in a searchbar with the package: searchfield.
Here's my code : search_bar.dart
class SearchBar extends StatefulWidget {
const SearchBar({Key? key}) : super(key: key);
@override
State<SearchBar> createState() => _SearchBarState();
}
class _SearchBarState extends State<SearchBar> {
static GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextEditingController searchController = new TextEditingController();
@override
Widget build(BuildContext context) {
final users = Provider.of<List<AppUserData>>(context);
return Form(
key: _formKey,
child: SearchField(
suggestions: users
.map((e) =>
SearchFieldListItem(e.toString(), child: Text(e.toString())))
.toList(),
controller: searchController,
searchStyle: const TextStyle(color: dLightGrey),
searchInputDecoration: const InputDecoration(
contentPadding: EdgeInsets.fromLTRB(0, 0, 0, 0),
filled: true,
fillColor: dDarkGrey,
prefixIcon: Icon(
SocketIconv2.ic_search,
color: dLightGrey,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
hintStyle: TextStyle(
color: dLightGrey,
fontFamily: 'SegoeUI',
fontSize: 18,
fontWeight: FontWeight.w300),
hintText: 'Search',
)),
);
}
}
database.dart
class DatabaseService {
final String? uid;
DatabaseService({this.uid});
final CollectionReference userCollection =
FirebaseFirestore.instance.collection("users");
Future<void> saveUser(String name, String username) async {
return await userCollection
.doc(uid)
.set({'name': name, 'username': username});
}
AppUserData _userFromSnapshot(DocumentSnapshot snapshot) {
return AppUserData(
name: snapshot['name'], uid: uid, username: snapshot['username']);
}
Stream<AppUserData> get user {
return userCollection.doc(uid).snapshots().map(_userFromSnapshot);
}
List<AppUserData> _userListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
return _userFromSnapshot(doc);
}).toList();
}
Stream<List<AppUserData>> get users {
return userCollection.snapshots().map(_userListFromSnapshot);
}
getUserByUsername(String searchField) async {
return await userCollection
.where("username", isGreaterThanOrEqualTo: searchField)
.get();
}
}
The parent widget of the search bar :
class _HomePageState extends State<HomePage> {
final AuthentificationService _auth = AuthentificationService();
String myName = '';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final _scaffoldKey = GlobalKey<ScaffoldState>();
return StreamProvider<List<AppUserData>>.value(
initialData: [],
value: DatabaseService().users,
child: Scaffold(
(Everything else is UI)
And finally here's user.dart:
class AppUser {
final String? uid;
AppUser({this.uid});
}
class AppUserData {
final String? uid;
final String name;
final String username;
AppUserData({this.uid, required this.name, required this.username});
}
With my actual Code I got the Text: "Instance of 'AppUserData' instead of the username I asked for. Thanks in advance for the help :)
CodePudding user response:
You render e.toString()
in this code:
child: SearchField(
suggestions: users
.map((e) =>
SearchFieldListItem(e.toString(), child: Text(e.toString())))
.toList(),
Since you don't override toString
in your AppUser
class, you get the default implementation, which indeed returns the class name.
If you want to show the user's name, either render e.name
or override toString
in AppUser
to return the string you want.