How to toLowerCase() on data from Flutter Firestore? - firebase

I made an application and coded a search system between documents in the application. But there is a problem:
The incoming record is registered as "Durmuş Bolat" in Firestore. And as you can see, the letter D of Durmuş is capitalized. That's why I have to capitalize the first letter in the search. And that's a problem.
I want to get the result of "Durmuş Bolat" even if I write it in the following ways:
durmuş bolat
DURMUŞ BOLAT
DuRmUs BoLaT
As a solution to this, I thought of shrinking the searched content and all the incoming content. So all incoming data and searched content will be downsized with toLowerCase.
I don't have the slightest idea where to place this toLowerCase code. Can you help me?
Codes:
var _searchText;
return Scaffold(
appBar: AppBar(
title: Container(
height: 50,
width: 250,
child: TextFormField(
autofocus: true,
style: TextStyle(color: Colors.white),
onChanged: (value) {
setState(() {
_searchText = value;
});
},
),
),
),
body: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 0.8, //MediaQuery.of(context).size.height * 0.8,
child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance.collection('bolatTamir').where('nameSurname', isGreaterThanOrEqualTo: _searchText).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
return InkWell(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(snapshot.data!.docs[index].data()['urunFotografi']),
),
title: Text(snapshot.data!.docs[index].data()['nameSurname'], style: TextStyle(fontSize: 20),),
subtitle: Text(snapshot.data!.docs[index].data()['yapildiMi'] == false ? 'Tamamlanmadı' : 'Tamamlandı', style: TextStyle(fontSize: 17),),
trailing: Text(snapshot.data!.docs[index].data()['tamirUcreti'], style: TextStyle(fontSize: 20),),
),
);
},
);
},
),
),
],
),
);
Thank you in advance for your help.

To my knowledge, lower-casing text that is already stored is not possible with Firebase. One can only lower-case the search term.
If it is just names and not tons of text, one could
.split(' ') these names, then
.toLowerCase() all resulting words, then
store them in a search-index-collection.
Then, search this search-index-collection and resolve the $userId.
.
users/34td24y3gtdb724/
{
name: 'Durmuş Bolat'
}
searchindex/
{
word: 'durmuş',
userId: 34td24y3gtdb724
word: 'bolat',
userId: 34td24y3gtdb724
}
Google itself asks to use Third-Party-Providers for full text search:
https://cloud.google.com/firestore/docs/solutions/search
Also, there is an approach to generate permutations as an Array:
https://medium.com/flobiz-blog/full-text-search-with-firestore-on-android-622af6ca5410

Related

Flutter - How to make a call on Flutter Firestore, return value if it contains?

I'm building a system. Purpose product search. But I'm having a problem with this search. I want this search system like this: If what the person is looking for is in any value, it should be returned as a result. For example, if the person is looking for shoes as a product, when I type sho, I want it to come to the listView.
Or let me give you another example: Finding the glass when typing gla for glass. How can I make this search system?
Firestore:
I tried a code like this:
Container(
height: 200,
child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance.collection("bolatAktar").where("urunAdi", isEqualTo: _arananUrun).snapshots(), // !!!!!!!!!!!!!!<<<<<<<<<<<<<<<<<<<<<
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
return InkWell(
child: ListTile(
leading: Icon(Icons.label),
title: Text(snapshot.data!.docs[index].data()["urunAdi"], style: TextStyle(fontSize: 20),),
),
onTap: () {
showModalBottomSheet(
isScrollControlled:true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
context: context,
builder: (context) {
return FractionallySizedBox(
heightFactor: 0.93,
child: Container(
padding: EdgeInsets.all(25),
height: MediaQuery.of(context).size.height * 0.5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Product name:", style: TextStyle(fontSize: 20)),
SizedBox(height: 10),
TextFormField(
style: TextStyle(fontSize: 19),
decoration: InputDecoration(
border: OutlineInputBorder(),
),
initialValue: snapshot.data!.docs[index].data()["urunAdi"],
),
]
)
),
);
}
);
},
);
},
);
}
},
),
),
Result:
Thank you in advance for your help and valuable information.
Google Firestore: Query on substring of a property value (text search)
Is there a way to search sub string at Firestore?
Firestore Comparison Operators - contains, does not contain, starts with
I have reviewed the above topics, but they did not contribute because they are not up to date.

How to make a call on Flutter Firestore, return value if it contains? [duplicate]

This question already has answers here:
Google Firestore: Query on substring of a property value (text search)
(25 answers)
Is there a way to search for substrings in Firestore?
(1 answer)
Firestore Comparison Operators - contains, does not contain, starts with
(2 answers)
Closed 10 months ago.
I'm building a system. Purpose product search. But I'm having a problem with this search. I want this search system like this: If what the person is looking for is in any value, it should be returned as a result. For example, if the person is looking for shoes as a product, when I type sho, I want it to come to the listView.
Or let me give you another example: Finding the glass when typing gla for glass. How can I make this search system?
Firestore:
I tried a code like this:
Container(
height: 200,
child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance.collection("bolatAktar").where("urunAdi", isEqualTo: _arananUrun).snapshots(), // !!!!!!!!!!!!!!<<<<<<<<<<<<<<<<<<<<<
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
return InkWell(
child: ListTile(
leading: Icon(Icons.label),
title: Text(snapshot.data!.docs[index].data()["urunAdi"], style: TextStyle(fontSize: 20),),
),
onTap: () {
showModalBottomSheet(
isScrollControlled:true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
context: context,
builder: (context) {
return FractionallySizedBox(
heightFactor: 0.93,
child: Container(
padding: EdgeInsets.all(25),
height: MediaQuery.of(context).size.height * 0.5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Product name:", style: TextStyle(fontSize: 20)),
SizedBox(height: 10),
TextFormField(
style: TextStyle(fontSize: 19),
decoration: InputDecoration(
border: OutlineInputBorder(),
),
initialValue: snapshot.data!.docs[index].data()["urunAdi"],
),
]
)
),
);
}
);
},
);
},
);
}
},
),
),
Result:
Thank you in advance for your help and valuable information.

How can I update Listview in Streambuilder in flutter

I have a streambuidler widget that contains a listview to display whom the current user has recently chatted with. When the current user receives a message that message should be pushed to the top of the listview, however that message is always display at the bottom of the list view, it's only display on the top if I refresh my screen.
NoSearchResultScreen() {
final Orientation orientation = MediaQuery.of(context).orientation;
print("hasAlreadyChatWithSomeone: $hasAlreadyChatWithSomeone");
return hasAlreadyChatWithSomeone
? StreamBuilder<QuerySnapshot>(
stream: (FirebaseFirestore.instance
.collection("user")
.where("id", isEqualTo: currentUserId)
.snapshots()),
builder: (context, snapshot) {
List<ProfileChatWith> chatWithList = [];
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: circularProgress(),
);
}
if (snapshot.hasData) {
final chatWithSnapshot = snapshot.data?.docs.first['chatWith'];
//print("chatWithSnapshot: $chatWithSnapshot");
for (var userChatWith in chatWithSnapshot) {
final user = ProfileChatWith(
userId: userChatWith,
currentUserId: currentUserId,
);
chatWithList.add(user);
//print("I have chatted with: $userChatWith");
}
return Container(
width: MediaQuery.of(context).size.width,
child: ListView(
//shrinkWrap: true,
children: chatWithList,
),
);
} else {
return Center(
child: circularProgress(),
);
}
},
)
: Container(
child: Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Icon(
Icons.group,
color: Colors.greenAccent,
size: 200.0,
),
Text(
"Search Users",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.greenAccent,
fontSize: 50.0,
fontWeight: FontWeight.bold),
)
],
),
),
);
}
Try reverse: true,
return SizedBox(
width: MediaQuery.of(context).size.width,
child: ListView(
reverse: true,
children: chatWithList,
),
);
Use Listview.builder for performance optimization
return SizedBox(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
reverse: true,
itemBuilder: (BuildContext context, int index) => chatWithList[index],
),
);
The solution which worked is as below, #Leo Tran own words
I found a way to solve my question is that I will rebuild my widget whenever the data got updated.

Show total firestore documents created by a user in Flutter

How would I go about showing the number of documents created by a user in Flutter?
I have come across this code in a stackoverflow post but unsure how to display that in text Firestore.instance.collection('products').snapshots().length.toString();
Another example, this is how I'm showing the users the First letter of their name in a Fittedbox
FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
width: 80,
height: 80,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffff8a93),
Color(0xffffbf81)
],
begin: Alignment.topLeft,
end: Alignment.bottomRight
),
shape: BoxShape.circle,
),
padding: EdgeInsets.all(20.0),
child: BlocBuilder(
cubit: BlocProvider.of<UserBloc>(context),
builder: (context, User user) {
return AutoSizeText(
(user.firstName?.isEmpty == true) ?
"CN"
:
'${user.firstName[0].toUpperCase()}',
style: GoogleFonts.roboto(
textStyle: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 50,
color: Colors.white,
),
),
textAlign: TextAlign.left,
);
}
),
),
)
This line Firestore.instance.collection('products').snapshots().length.toString(); returns the count of all products, not from a specific user. If you want to filter your query for a specific user you can try below syntax assuming you have a user field in your products document :
FirebaseFirestore.instance
.collection('products')
.where('user', is: 'admin')
.get()
.then(...);
You can use a StreamBuilder to get the data from the snapshots and get the length of the documents to display it in a Text widget.
Check out this sample code:
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('products').snapshots(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(
child: CircularProgressIndicator(),
);
} else {
var snapshotDocumentLength = snapshot.data.documents.length;
return Text(snapshotDocumentLength.toString());
}
})

Unique Counters For All Items In ListView - Flutter

Disclaimer: I saw some solutions on stackoverflow but none of them had listviews generated with data from firestore. So a hint on that questions will not help me :/
Hey
I have a little problem with my counters within my ListView from the Firestore database. As you can see below, I am trying to create unique counters for each entry in the list from the database. The number currently changes with each entry, so it is identical everywhere.
It may be useful to know when you try to help me solving that problem, that in the following I still need the number of the counter in order to save it in the database.
(I saw other solutions where that point was pretty heavy)
So here is the extract of my code:
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection(globals.selectedKat)
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return Padding(
padding: const EdgeInsets.all(20.0),
child: GridView.count(
children: snapshot.data.docs.map((document) {
return Center(
[...]
child: Container(
[...]
child: Column(
children: [
Center(
child: Text(
document["titel"],
)),
Row(
children: [
IconButton(
onPressed: () {
setState(() {
counter++;
});
},
icon: Icon(Icons.add_circle_outline)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
counter.toString(),
style: TextStyle(
color: Colors.white, fontSize: 30),
),
),
IconButton(
iconSize: 40,
color: Colors.white,
onPressed: () {
setState(() {
counter--;
});
},
icon: Icon(Icons.remove_circle_outline))
],
)
],
)),
);
}).toList(),
),
);
}
}),
And here a Screen of my sim:
If anything is not clear I'll answer in a few minutes.
Thanks for helping me :)

Resources