How to display items from Firestore by recently added in Flutter? - firebase

There's a problem which I'm trying to solve, it is displaying data by recently added to Firestore, through Flutter. What can be done in my case?
In React I would achieve this with useState hook, how can this be achieved in Flutter?
I read about .sort(); method, is that a right way of doing this?
Code:
Form.dart
class FormText extends StatelessWidget {
final String _labelText = 'Enter your weight..';
final String _buttonText = 'Save';
final _controller = TextEditingController();
final dateFormat = new DateFormat.yMMMMd().add_jm();
final _collection =
FirebaseFirestore.instance.collection('weightMeasurement');
void saveItemToList() {
final weight = _controller.text;
if (weight.isNotEmpty) {
_collection.add({
'weight': weight,
'time': dateFormat.format(DateTime.now()),
});
} else {
return null;
}
_controller.clear();
}
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(
child: TextField(
keyboardType: TextInputType.number,
controller: _controller,
decoration: InputDecoration(
labelText: _labelText,
),
),
),
FlatButton(
color: Colors.blue,
onPressed: saveItemToList,
child: Text(
_buttonText,
style: TextStyle(
color: Colors.white,
),
),
),
],
);
}
}
Measurements.dart
class RecentMeasurement {
Widget buildList(QuerySnapshot snapshot) {
return ListView.builder(
reverse: false,
itemCount: snapshot.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.docs[index];
return Dismissible(
background: Container(color: Colors.red),
key: Key(doc.id),
onDismissed: (direction) {
FirebaseFirestore.instance
.collection('weightMeasurement')
.doc(doc.id)
.delete();
},
child: ListTile(
title: Expanded(
child: Card(
margin: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
Text('Current Weight: ' + doc['weight'] + 'kg'),
Text('Time added: ' + doc['time'].toString()),
],
),
),
),
),
);
},
);
}
}
Layout.dart
class Layout extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
FormText(),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('weightMeasurement')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return Expanded(
child: RecentMeasurement().buildList(snapshot.data),
);
}),
],
),
);
}
}

You can try order by . Here is an example
firestoreDb.collection("weightMeasurement")
.orderBy("date", Query.Direction.ASCENDING)

You have to use "orderBy" on your collection, but previously You have to store something called timestamp. Make sure when You upload Your items to Firebase to also upload DateTime.now() along with Your items so You can order them by time. Do not forget to use Ascending direction since it will show you Your items ordered correctly.

Related

how to listen to a change in a stream from firebase

I am getting data from this stream builder and showing it inside a stateful widget.
Widget chatRoomsLists() {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('chatrooms').orderBy("lastMessageSendTs", descending: true)
.where("users", arrayContains:myUserName)
.snapshots(),
builder: (context, snapshot){
return snapshot.hasData ? ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
itemBuilder: (context,index){
DocumentSnapshot ds = snapshot.data!.docs[index];
return ChatRoomListTile(ds['lastMessage'], ds.id,myUserName! );
}) : Center(child: CircularProgressIndicator());
}) ;
}
and showing it here
class ChatRoomListTile extends StatefulWidget {
final String lastMessage , chatRoomId, myUsername;
ChatRoomListTile(this.lastMessage, this.chatRoomId, this.myUsername,);
#override
_ChatRoomListTileState createState() => _ChatRoomListTileState();
}
class _ChatRoomListTileState extends State<ChatRoomListTile> {
String profilePicUrl = 'https://miro.medium.com/max/875/0*H3jZONKqRuAAeHnG.jpg' , name = '' ,username = "";
getThisUserInfo() async {
print('userinfo called');
username = widget.chatRoomId.replaceAll(widget.myUsername, "").replaceAll("_", "");
QuerySnapshot querySnapshot = await DatabaseMethods().getUserInfo(username);
// print("something bla bla ${querySnapshot.docs[0].id} ${querySnapshot.docs[0]["name"]} ${querySnapshot.docs[0]["profileURL"]}");
name = "${querySnapshot.docs[0]["name"]}";
profilePicUrl = "${querySnapshot.docs[0]["profileURL"]}";
setState(() {});
}
#override
void initState() {
getThisUserInfo();
super.initState();
}
#override
Widget build(BuildContext context) {
print('BUILDING IS CALLED');
return GestureDetector(
onTap: () {
print('name is $username and ${widget.myUsername}');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Chatting(username, widget.myUsername)));
},
child: Column(
children: [
Container(
margin: EdgeInsets.symmetric(vertical: 8),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(30),
child: Image.network(profilePicUrl,
height: 40,
width: 40,
),
),
SizedBox(width: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(fontSize: 16),
),
SizedBox(height: 3),
SizedBox(width: 220,
child: Text(widget.lastMessage,overflow: TextOverflow.ellipsis)),
],
)
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Divider(thickness: 0.5 ,),
)
],
),
);
}
}
I want to call get this future getThisUserInfo every time there is change in widget.lastmessage . How can i do that ?
When i am calling this future inside the build , It is getting called again and again non stop .So how can i only call this when there is a new message only ?
I would suggest you to review the construction of your builder and check the snapshot().listen() method, you can refer to this similar issue for that.
To your follow-up question, it is hard to say what is causing this duplicated update, as it can be a number of things and nothing in your code indicates that, so that being said, I would think of some logic that allows you to check if the update you want to make already happened, perhaps spending a read, which is less expensive than a write.

Firebase Chat messages not ordering correctly

I have just completed this basic chat app based on a tutorial on YouTube. NO user name needed for using it. But my messages are not ordering correctly. It is sorting as auto generated ID on FireStore. There are total two field in Firebase "message" collection that I have created
"username" {this user name randomly generated by FireBase as user ID. example: 1Mrayhz7EKL7MklHXUxv}
"messagetext"
I don't understanding what should I do now
//Here's the code
class MyApp extends StatelessWidget {
final TextEditingController messaingTextBox = TextEditingController();
final CollectionReference cr =
FirebaseFirestore.instance.collection('messages');
#override
Widget build(BuildContext context) {
body:
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: StreamBuilder(
stream: cr.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return ListView.builder(
reverse: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
children: [
Row(
children: [
Container(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Text(
snapshot.data.documents[index]
.data()['username'],
),
),
),
SizedBox(
width: 10,
),
Container(
// width: 38.0,
width: MediaQuery.of(context).size.width / 1.6,
child: Padding(
padding: const EdgeInsets.all(9.0),
child: Column(
children: [
Text(
snapshot.data.documents[index]
.data()['messagetext'],
),
],
),
),
),
],
),
],
),
);
},
);
},
),
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
cursorColor: HexColor("#003F51"),
style: TextStyle(color: Colors.black),
controller: messaingTextBox,
),
),
),
FloatingActionButton(
onPressed: () {
Message m = Message(
username: "unkown ",
messagetext: messaingTextBox.text.toString());
cr.add(m.mapMessages());
},
child: Icon(Icons.send),
),
],
),
],
);
}
}
class Message {
final String username;
final String messagetext;
Message({this.messagetext, this.username});
mapMessages() {
return {'messagetext': messagetext, 'username': username};
}
}
Please help me for solving this isue
You need to add third field to store time.
Then in the code try to add orderBy operator.
FirebaseFirestore.instance.collection('messages')
.orderBy('time_field', descending: true);
It's quite simple just add a timestamp with each message lets say createdAt, and the use
NOTE: The type of createdAt must be Date
FirebaseFirestore.instance.collection('messages').orderBy('createdAt', descending: true)

How do i add cart page for my ecommerce app on flutter?

Im using firebase as a backend. I retrieved products from firebase using stream builder .I looked into providers but all the tutorials used providers for the products page too.Can i use provviders only for cart?How do i do it?Or is there any other way to implement cart page?
here's the code for the products page.
class Shop extends StatefulWidget {
final User currentUser;
final String prodId;
final String onwerId;
Shop({ this.currentUser,
this.prodId,
this.onwerId});
#override
_ShopState createState() => _ShopState( prodId: this.prodId,ownerId:this.onwerId);
}
class _ShopState extends State<Shop> {
final _firestore = Firestore.instance;
String postOrientation = "grid";
String shopOrientation = "grid";
bool isFollowing = false;
bool isLoading = false;
String uid="";
String prodId;
String ownerId;
Prod products;
_ShopState({
this.prodId, this.products,this.ownerId,
});
#override
Widget build(BuildContext context) {
return
Scaffold(
appBar: AppBar(backgroundColor: kSecondaryColor,
title: Text( 'Shop',
style: TextStyle(
fontFamily :"MajorMonoDisplay",
fontSize: 35.0 ,
color: Colors.white),),
iconTheme: new IconThemeData(color: kSecondaryColor),
),
backgroundColor: kPrimaryColor,
body:StreamBuilder(
stream: Firestore.instance.collectionGroup("userProducts").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return circularProgress();
} else {
return new ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.documents[index];
return new ShopItem(
shopmediaUrl: ds['shopmediaUrl'],
productname: ds['productname'],
price: ds['price'],
photoUrl: ds['photoUrl'],
username: ds['username'],
prodId: ds['prodId'],
userId: ds['userId'],
ownerId: ds['ownerId'],
);
}
);
}
}
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black38,
onPressed: ()
async{ Navigator.push(context, MaterialPageRoute(builder: (context) =>Uploadecom(currentUser: currentUser, )));
},
child: Icon(Icons.add_box),
),
);
}
}
class ShopItem extends StatelessWidget {
final String username;
final String prodId;
final String ownerId;
final String photoUrl;
final String shopmediaUrl;
final String productname;
final String price;
final String userId;
ShopItem({
this.ownerId,
this.prodId,
this.shopmediaUrl,
this.username,
this.photoUrl,
this.price,
this.productname,
this.userId,
});
showProduct(context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductScreen(
prodId: prodId,
userId: ownerId,
),
),
);
}
#override
Widget build(BuildContext context) {
// configureshopmediaPreview(context);
return
//
Column( children: <Widget>[
Stack(
children: <Widget>[
Container(
child:Row(
children: <Widget>[
Expanded(
child: Container(
// width: 360,
height: 400.0,
child:AspectRatio(
aspectRatio: 16 / 9,
child:Container(
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
shopmediaUrl),
fit: BoxFit.cover),
),
),
),
),
),
)],
),
),
Positioned(
bottom: 10,
left: 10,
child: Container(
height: 40,
width: 40,
child: cachedNetworkImage(photoUrl),
),
),
Positioned(
bottom: 20,
left: 60,
child: Container(
child: Text(username,style: TextStyle(color: Colors.white,fontWeight:FontWeight.bold),),
),
),
Container(
alignment: Alignment.bottomRight,
child: Container(
alignment: Alignment.bottomRight,
child: GFButton(
onPressed: () => showProduct(context) ,
text: "More",
icon: Icon(Icons.card_travel),
shape: GFButtonShape.pills,
),
),
),
],
),
Row(
children: <Widget>[
Container(
child: Text(productname,style: TextStyle(color: kText,fontSize: 30.0,fontWeight:FontWeight.bold),),
),
],
),
Row(
children: <Widget>[
Container( child: Text('₹',style: TextStyle(color: kText,)),
),
Container(
child: Text(price,style: TextStyle(color: kText,fontSize: 20.0,fontWeight:FontWeight.bold),),
),
],
),
Divider(color: kGrey,),
],
);
}
}
Yes, you can use provider(or any state management solution) for the cart page only, but you have to persist those cart products so when the user logs out or exit your app and returns he will find his cart products still available, for persisting I suggest creating a carts collection in your Firestore and for every user create a cart.

Firestore value returns only one value

whenever I try to retrieve data from firestore,only one part is called
You can see that I have a ListTile with a title and a Subtitle
Now only the data in the subtitle is being displayed and it requires no null indication
But the title requires the null indication but still it does not returns the string This is my firestore
Thank You
// ...
class SearchPage extends StatefulWidget {
#override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
TextEditingController searchController = TextEditingController();
Future<QuerySnapshot> searchResultsFuture;
handleSearch(String query){
Future<QuerySnapshot> users = usersReference.where("profilename",isGreaterThanOrEqualTo: query ).getDocuments();
setState(() {
searchResultsFuture = users;
});
//searchResultsFuture = users;
}
clearSearch(){
searchController.clear();
}
AppBar buildSearchField(){
return AppBar(
backgroundColor: Colors.white,
title: TextFormField(
controller: searchController,
decoration: InputDecoration(
hintText: "Search Your Friends",
filled: true,
prefixIcon: Icon(
Icons.account_box,
size: 28.0,
),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: clearSearch,
),
),
onFieldSubmitted: handleSearch,
),
);
}
Container buildNoContent(){
final Orientation orientation = MediaQuery.of(context).orientation;
return Container(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Icon(Icons.group, color: Colors.white,size: orientation == Orientation.portrait ? 400.0 : 200.0 ,),
Text("Find Users",textAlign: TextAlign.center,style: TextStyle(color: Colors.white,fontStyle: FontStyle.italic,fontWeight: FontWeight.w600,fontSize: 65.0),),
],
),
);
}
buildSearchResults() {
return FutureBuilder(
future: searchResultsFuture,
builder: (context, snapshot){
if(!snapshot.hasData){
return circularProgress();
}
List<UserResult> searchResults = [];
snapshot.data.documents.forEach((doc){
User user = User.fromDocument(doc);
UserResult searchResult = UserResult(user);
searchResults.add(searchResult);
});
return ListView(
children: searchResults,
);
}
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor.withOpacity(0.8) ,
appBar: buildSearchField(),
body: searchResultsFuture == null ? buildNoContent() : buildSearchResults(),
);
}
}
class UserResult extends StatelessWidget {
final User eachUser;
UserResult(this.eachUser);
#override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).primaryColor.withOpacity(0.7),
child: Column(children: <Widget>[
GestureDetector(
onTap: ()=> print("tapped"),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.grey,
backgroundImage: CachedNetworkImageProvider(eachUser.url),
),
title: eachUser.profileName != null ? Text(eachUser.profileName,
style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),): 'User',
subtitle: Text(eachUser.username,style: TextStyle(color: Colors.white),),
),
),
Divider(
height: 2.0,
color: Colors.white54,
),
],),
);
}
}
try uploading a more detailed code so as to get insights of what might be wrong.
I thinnk you shoud try to call setSate in
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance.addPostFrameCallback((callback) async {
/// logic here!
eachUser = get data from firebase;
after that call setState();
});
}
I think the proplem is:
Future<QuerySnapshot> users = usersReference.where("profilename",isGreaterThanOrEqualTo: query ).getDocuments();
setState(() {
searchResultsFuture = users;
});
searchResultsFuture get value when users hadn't completed

Stream builder from firestore to flutter

I am wondering how to get data from firestore to flutter app using the streambuilder. I created the necessary Boilerplate code I have the widget built and working and in the below code
headimageassetpath is nothing but a URL string which exists in the firestore.
#override
Widget build(BuildContext context) {
return Scaffold(
body:
new StreamBuilder(
stream: Firestore.instance.collection('Items').snapshots(),
builder: (_, AsyncSnapshot<QuerySnapshot> snapshot) {
var items = snapshot.data?.documents ?? [];
return new Lost_Card(
headImageAssetPath : snapshot.data.documents.map()(['url'],)
);
},
)
My firestore:
full code:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class LostPage extends StatefulWidget {
#override
_LostPage createState() => new _LostPage();
}
class _LostPage extends State<LostPage> {
//temp vars
final String firebasetest = "Test";
//firestore vars
final DocumentReference documentReference =
Firestore.instance.document("Items/Rusty");
//CRUD operations
void _add() {
Map<String, String> data = <String, String>{
"name": firebasetest,
"desc": "Flutter Developer"
};
documentReference.setData(data).whenComplete(() {
print("Document Added");
}).catchError((e) => print(e));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:
new StreamBuilder(
stream: Firestore.instance.collection('Items').snapshots(),
builder: (_, AsyncSnapshot<QuerySnapshot> snapshot) {
var items = snapshot.data?.documents ?? [];
return new Lost_Card(
headImageAssetPath : snapshot.data.documents.map()(['url'],)
);
},
)
/*new Lost_Card(
headImageAssetPath: "https://i.imgur.com/FtaGNck.jpg" ,
title: "Mega Dish",
noro: "old",
)*/,
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
onPressed: _add),
);
}
}
class Lost_Card extends StatelessWidget
{
//All the card variables
final String headImageAssetPath;
final IconData icon;
final Color iconBackgroundColor;
final String title;
final String noro;
final int price;
final ShapeBorder shape;
Lost_Card({
this.headImageAssetPath, //used
this.icon,
this.iconBackgroundColor,
this.title, //used
this.noro, //used
this.price,
});
#override
Widget build(BuildContext context) {
// TODO: implement build
return GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: <Widget>[
Card(
child: Column(
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.height / 2.5,
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
headImageAssetPath),
fit: BoxFit.cover),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: FractionalOffset.topLeft,
child: CircleAvatar(
backgroundColor: Colors.redAccent,
radius: 15.0,
child: Text(
noro,
textScaleFactor: 0.5,
),
),
),
),
Align(
alignment: FractionalOffset.topRight,
child: Container(
color: Colors.blueAccent,
height: 35.0,
width: 35.0,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_circle),
Text(
"1P",
textScaleFactor: 0.5,
),
],
),
),
),
),
],
),
),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
alignment: FractionalOffset.bottomCenter,
child: Text(
title,
style: TextStyle(
fontWeight: FontWeight.w700,
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlatButton(
child: Text(
"Add To Cart",
style: TextStyle(color: Colors.grey[500]),
),
onPressed: () => null,
),
Text(
"\$5",
style: TextStyle(color: Colors.grey[500]),
)
],
)
],
),
),
],
);
}
}
Actual App
Please shed some light on this. Tks.
This should work for one item
body: new StreamBuilder(
stream: Firestore.instance.collection("collection").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text(
'No Data...',
);
} else {
<DocumentSnapshot> items = snapshot.data.documents;
return new Lost_Card(
headImageAssetPath : items[0]["url"]
);
}
If you want to create list builder from many documents use it like this
return new ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.documents[index];
return new Lost_Card(
headImageAssetPath : ds["url"];
);
Accessing documents using StreamBuilder in Flutter 2
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('products').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot doc = snapshot.data!.docs[index];
return Text(doc['name']);
});
} else {
return Text("No data");
}
},
)
As per new changes 2021 in Firebase FireStore you can retrieve data from collection using StreamBuilder as below
final _mFirestore = FirebaseFirestore.instance;
return StreamBuilder<QuerySnapshot>(
stream:
_mFirestore.collection(kFirebaseCollectionName).snapshots(),
builder: (context, snapshots) {
if (!snapshots.hasData) {
return Center(
child: Text('Data not available',),
);
}
final messages = snapshots.data.docs;
List<Text> textWidgets = [];
messages.forEach((element) {
final messageText = element['text'];
final messageSender = element['sender'];
final textWidget = Text('$messageText, $messageSender');
textWidgets.add(messageBubbleWidget);
});
},
);
Card buildItem(DocumentSnapshot doc) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'name: ${doc.data['name']}',
style: TextStyle(fontSize: 24),
),
Text(
'todo: ${doc.data['todo']}',
style: TextStyle(fontSize: 20),
),
Text(
'Age: ${doc.data['age']}',
style: TextStyle(fontSize: 10),
),
SizedBox(
height: 12,
),
],
)
],
),
),
); }
For other persons who will face the same problem, the card and stream builder will represent a solution. The Widget has the Card just before it declaration and has inside the body the next part:
body: ListView(
padding: EdgeInsets.all(8),
children: <Widget>[
Form(
key: _formKey,
child: buildTextFormField(),
),
StreamBuilder<QuerySnapshot>(
stream: db
.collection('CRUD')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList());
} else {
return SizedBox();
}
},
)
],
),
Update for 2022, Flutter 2.10, cloud_firestore: ^3.1.11. You can retrieve data from collection using StreamBuilder
Stream collectionStream = FirebaseFirestore.instance.collection('users').snapshots();
StreamBuilder<QuerySnapshot>(
builder: (context, snapshot) {
if (snapshot.hasData) {
final messages = snapshot.data!.docs;
List<Text> messageWidgets = [];
for (var element in messages) {
final messageText = element['text'];
final messageSender = element['sender'];
final messageWidget =
Text('$messageText from $messageSender');
messageWidgets.add(messageWidget);
}
return Column(
children: messageWidgets,
);
}
return const Text('Error');
},
stream:collectionStream),
StreamBuilder<List<UData>>(
stream: AdminData().getDrivers,
builder: (context, snapshot) {
return ListView(
children: snapshot.data.map((document) {
return hadCard(
widget: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
hadText(title: document.name),
hadText(title: document.phone),
hadText(title: document.Driver),
],
),
);
}).toList(),
);
}),

Resources