How to order documents by a field content in firestore flutter - firebase

I have a collection of rooms for a hotel. When i add a new one or show the rooms list, they don't show from 1 to 5. Is there a way to order the rooms by their number?
The documents in room collection have their id generated automatically, and every room have a field called room number (ex : 1,2,3 ..)
final rooms = Provider.of<List<Room>>(context) ?? [];
return StreamProvider<List<Room>>.value(
initialData: [],
value: DatabaseService().singleRoom,
child: Scaffold(
appBar: AppBar(
title: Text("Liste des chambre single"),
backgroundColor: Colors.blue,
elevation: 2.0,
leading: IconButton(icon: Icon(Icons.chevron_left),onPressed: ()=> Navigator.pushReplacementNamed(context, '/room_type_screen'),),
actions: [
ElevatedButton.icon(
icon: Icon(Icons.home),
label: Text(""),
onPressed: ()=> Navigator.pushReplacementNamed(context, '/admin_home'),
),
ElevatedButton.icon(
icon: Icon(Icons.add),
label: Text(""),
onPressed: ()=> Navigator.pushNamed(context, '/add_room'),
),
],
),
body: ListView.builder(
itemCount: rooms.length,
itemBuilder: (context,index){
return RoomTile(room : rooms[index]);
},
),
),
Widget build(BuildContext context) {
void deleteRoomFromDatabase(String id){
final CollectionReference singleRoomCollection = FirebaseFirestore.instance.collection("rooms/single/room");
singleRoomCollection.doc(id).delete();
}
return Padding(
padding: EdgeInsets.only(top: 10.0),
child: Card(
margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
child: GridTileBar(
backgroundColor: Color(0xFFBDBDBD),
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.orange,
// backgroundImage: AssetImage('assets/6074.jpg'),
child: Text("${room.numChambre.toString().substring(1)}",
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
fontWeight: FontWeight.bold
),
),
),
title: room.reserver?Text("Chambre réservé"):Text('Chambre disponible',style: TextStyle(fontSize: 20),),
subtitle: Text("Prix : "+room.prix.toString()),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: (){
deleteRoomFromDatabase(room.roomId);
},
),
),
),
);
}

if you want to order your result from:
FirebaseFirestore.instance.collection("rooms/single/room")
use the .orderBy() function.
FirebaseFirestore.instance.collection("rooms/single/room").orderBy("FieldInFirestoreToOrderBy", descending: true/false)
If you wanna filter the result you can also use the .where function

Related

Flutter Firebase document.id update problem

I've problem about send 'document.id' value to another page.
My first page is this:
I want to update task's header and content. When user's tap to pencil, I navigate to this screen:
But, in the update screen there is a problem about 'document.id' as you see. To update the already exist document, I need the document id in the UpdateScreen page but I cant access. What can I do to solve?
My codes:
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Card(
child: ListTile(
title: Text(data['GorevBaslik']),
subtitle: Text(data['GorevIcerik']),
trailing: Wrap(
spacing: 12, // space between two icons
children: <Widget>[
IconButton(
icon: Icon(Icons.edit),
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UpdateStatusPage()));
}),
IconButton(
icon: Icon(Icons.remove),
onPressed: () async {
print(document.id);
// authService.removeStatus(document.id); //auth olarak değil status olarak değiştir service adını
},
), // icon-2
],
),
),
);
}).toList(),
);
and the update pages:
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.white, //change your color here
),
title: Text(
"Görev Oluştur",
style: TextStyle(color: Colors.white),
),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.only(top: 120.0, left: 25.0, right: 25.0),
child: Column(
children: [
TextFormField(
controller: gorevBaslikController,
decoration: InputDecoration(
prefixIcon: Icon(Icons.edit), labelText: "Güncellemek istediğiniz görev başlığı"),
),
TextFormField(
controller: gorevIcerikController,
decoration: InputDecoration(
prefixIcon: Icon(Icons.article_rounded),
labelText: "Yeni görev içeriği"),
maxLines: 3,
),
SizedBox(height: 15),
ElevatedButton(
onPressed: (){
//getStatus.addTask(gorevBaslikController.text, gorevIcerikController.text);
firestore.collection('Task').doc('${auth.currentUser?.email}').collection('tasks').doc(document.id).update(
{
'GorevBaslik': gorevBaslikController,
'GorevIcerik': gorevIcerikController,
}
);
},
child: Text(
"Güncelle",
style: TextStyle(color: Colors.white),
),
),
],
),
),
);
You should pass the documentId or document in the editing file to update the correct document.
UpdateScreen(#required this.documentID);
Pass documentID from the parent screen of UpdateScreen.

How to retrive a doc from firestore with its ID with flutter

I have a collection of user_profile in my app console. I want to retrieve a doc (a particular user profile with its user id [click to check][1]).
I know that FirebaseAuth.instance.currentUser; would give me the current login user ID but that is not what I want. I want to show the details of the clicked user, not the logged_in user, can't seem to find any answer here that was helpful. Please help guys
This is the method that gets the collection
Future<DocumentSnapshot> getUserData() {
var firebaseUser = FirebaseAuth.instance.currentUser;
_firestoreInstance
.collection('user_profile')
.doc(firebaseUser.uid)
.get()
.then((value) {
print(value.data());
return value.data();
});
}
and here is my future builder
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getUserData(),
// ignore: missing_return
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Error fetching user profile');
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> userData = snapshot.data.data();
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: () {
// Navigator.pushNamed(context, Homepage.id);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 30,
),
),
),
GestureDetector(
onTap: () {},
child: Stack(
children: [
CircleAvatar(
radius: 70,
backgroundColor: Colors.transparent,
child: ClipOval(
child: Image.asset('assets/avatar_profile.jpg'),
),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white60,
radius: 25,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.edit, color: Colors.blueGrey),
),
),
)
],
),
),
SizedBox(
height: 10,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${userData['nickname']}",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 3,
width: 20,
color: Colors.white,
),
Text(
// '7',
"{$userData['age]}",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Card(
child: Column(
children: [
ListTile(
leading: Icon(
Icons.person,
size: 40,
),
title: Text("About me"),
isThreeLine: false,
dense: true,
subtitle: Text("${userData['aboutMe']}"),
trailing: Icon(Icons.arrow_right),
)
],
),
),
),
Expanded(
child: Container(
width: 400,
child: ListView(
children: [
ProfileListTile(
leading: Icons.phone_in_talk,
title: 'Phone Number',
subtitle: "${userData['mobile']}",
),
ProfileListTile(
leading: Icons.add_location,
title: 'Current Location',
subtitle: "${userData['location']}",
),
ProfileListTile(
leading: FontAwesomeIcons.heartbeat,
title: 'Relationship Status',
subtitle: "${userData['maritalStatus']}",
),
ProfileListTile(
leading: Icons.people,
title: 'Gender',
subtitle: 'Male',
),
ProfileListTile(
leading: Icons.looks,
title: 'Interested In',
subtitle: "${userData['InterestedIn']}",
),
],
),
),
),
],
),
),
));
}
},
);
}
}
Your code is currently not returning anything from getUserData yet. The only return you have is inside the then function, and doesn't escape to the higher level.
The simplest way to fix it is by using await:
Future<DocumentSnapshot> getUserData() async {
var firebaseUser = FirebaseAuth.instance.currentUser;
var doc = await _firestoreInstance
.collection('user_profile')
.doc(firebaseUser.uid)
.get()
return doc.data();
}
It sounds like you would like your app's users to see other people's profile.
To do that, you would first have to accept the uid of the user to display the profile. Then you can pass the uid to the future like the following example:
class ProfilePage extends StatelessWidget {
const ProfilePage({
Key key,
#required this.uid, // Here you are receiving the uid of the currently viewd user's uid
}) : super(key: key);
final String uid;
#override
Widget build(BuildContext context) {
return FutureBuilder<Map<String, dynamic>>(builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error fetching user profile'));
}
final userProfile = snapshot.data;
return Column(
children: [
// Here you would paste the contents of your user profile widget
],
);
});
}
Future<Map<String, dynamic>> getUserData() async {
final snap =
await _firestoreInstance.collection('user_profile').doc(uid).get();
return snap.data();
}
}
I was able to solve this easily by just passing from usersCard to UserProfile (my bad, lolx), since I already have this data on list users screen, there was no need to fetching them again with FutureBuilder
class UsersCard extends StatelessWidget {
final Users usersDetails;
const UsersCard({Key key, #required this.usersDetails}) : super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) =>
UserProfile(userDetails: usersDetails))); //im passing the data here
},
child: Stack(
children: [
Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.network(
'https://placeimg.com/170/170/any',
fit: BoxFit.contain,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
),
Positioned(
left: 20,
bottom: 20,
child: IntrinsicHeight(
child: Row(
children: [
Text(
'${usersDetails.nickname}',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 2,
width: 20,
color: Colors.white,
),
Text(
'${usersDetails.age}',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900),
),
],
),
),
),
],
),
);
}
}
Here is my UsersProfile Screen
class UserProfile extends StatelessWidget {
final Users userDetails;
UserProfile({#required this.userDetails});
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: () {
// Navigator.pushNamed(context, Homepage.id);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 30,
),
),
),
GestureDetector(
onTap: () {},
child: Stack(
children: [
CircleAvatar(
radius: 70,
backgroundColor: Colors.transparent,
child: ClipOval(
child: Image.asset('assets/avatar_profile.jpg'),
),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white60,
radius: 25,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.edit, color: Colors.blueGrey),
),
),
)
],
),
),
SizedBox(
height: 10,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${userDetails.nickname}",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 3,
width: 20,
color: Colors.white,
),
Text(
// '7',
"{$userDetails.age}",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Card(
child: Column(
children: [
ListTile(
leading: Icon(
Icons.person,
size: 40,
),
title: Text("About me"),
isThreeLine: false,
dense: true,
subtitle: Text("${userDetails.aboutMe}"),
trailing: Icon(Icons.arrow_right),
)
],
),
),
),
Expanded(
child: Container(
width: 400,
child: ListView(
children: [
ProfileListTile(
leading: Icons.phone_in_talk,
title: 'Phone Number',
subtitle: "${userDetails.mobile}",
),
ProfileListTile(
leading: Icons.add_location,
title: 'Current Location',
subtitle: "${userDetails.location}",
),
ProfileListTile(
leading: FontAwesomeIcons.heartbeat,
title: 'Relationship Status',
subtitle: "${userDetails.maritalStatus}",
),
ProfileListTile(
leading: Icons.people,
title: 'Gender',
subtitle: 'Male',
),
ProfileListTile(
leading: Icons.looks,
title: 'Interested In',
subtitle: "${userDetails.interestedIn}",
),
],
),
),
),
],
),
),
),
);
}
}

FLUTTER Profile picture disappears when user leaves page

Please guys I really need help with this, I implemented an upload profile picture in my user profile page, everything works fine, the only problem is that the uploaded image disappears immediately when the user navigate away from this screen and come back to this same particular screen.
Looking forward to you awesome folks response, Thanks
This is the code that handles file selected and picture upload
class _UserProfileState extends State<UserProfile> {
DocumentSnapshot userDoc;
File _image;
String _uploadedFileURL;
Future chooseFile() async {
await ImagePicker.pickImage(source: ImageSource.gallery).then((image) {
setState(() {
_image = image;
});
});
uploadImage(_image);
}
Future<String> uploadImage(var imageFile) async {
StorageReference ref = FirebaseStorage.instance
.ref()
.child('chats/${Path.basename(_image.path)}}');
StorageUploadTask uploadTask = ref.putFile(imageFile);
var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
_uploadedFileURL = dowurl.toString();
return _uploadedFileURL;
}
This is my user profile page screen
#override
Widget build(BuildContext context) {
var firebaseUser = FirebaseAuth.instance.currentUser;
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('user_profile')
.doc(firebaseUser.uid)
.snapshots(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
userDoc = snapshot.data;
return SafeArea(
child: Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.edit,
color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return EditUserProfile(userData: userDoc);
},
),
);
},
),
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: () {
Navigator.pushNamed(context, Homepage.id);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 30,
),
),
),
GestureDetector(
onTap: chooseFile,
child: Stack(
children: [
CircleAvatar(
radius: 70,
backgroundColor: Colors.transparent,
child: Container(
child: _uploadedFileURL == null
? ImageBeforeUpload(
image: _image, //This shows immediately when user chooses an image
// onTap: chooseFile,
)
: ImageUploaded(
uploadedFileURL: _uploadedFileURL // //This shows when image has been uploaded successfully but disappears when user leaves page and come back to this page
),
),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white60,
radius: 25,
child: IconButton(
onPressed: chooseFile,
icon: Icon(Icons.edit, color: Colors.blueGrey),
),
),
)
],
),
),
SizedBox(
height: 10,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
userDoc.data()['nickname'] ?? '',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 3,
width: 20,
color: Colors.white,
),
Text(
userDoc.data()['age'] ?? '',
style: TextStyle(
color: Colors.white,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Card(
child: Column(
children: [
ListTile(
leading: Icon(
Icons.person,
size: 40,
),
title: Text("About me"),
isThreeLine: false,
dense: true,
subtitle: Text(userDoc.data()['aboutMe'] ?? ''),
trailing: Icon(Icons.arrow_right),
)
],
),
),
),
Expanded(
child: Container(
width: 400,
child: ListView(
children: [
ProfileListTile(
leading: Icons.phone_in_talk,
title: 'Phone Number',
subtitle: userDoc.data()['mobile'] ?? '',
),
ProfileListTile(
leading: Icons.add_location,
title: 'Current Location',
subtitle: userDoc.data()['location'] ?? '',
),
ProfileListTile(
leading: FontAwesomeIcons.heartbeat,
title: 'Relationship Status',
subtitle: userDoc.data()['maritalStatus'] ?? '',
),
ProfileListTile(
leading: Icons.people,
title: 'Gender',
subtitle: userDoc.data()['gender'] ?? '',
),
ProfileListTile(
leading: Icons.looks,
title: 'Interested In',
subtitle: userDoc.data()['interestedIn'] ?? '',
),
// Padding(
// padding: const EdgeInsets.symmetric(
// horizontal: 50.0, vertical: 10),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Column(
// children: [
// IconButton(
// icon: Icon(Icons.phone,
// color: Colors.white),
// onPressed: null),
// Text(
// 'Call Me',
// style: klistTileTitle,
// ),
// ],
// ),
// Column(
// children: [
// IconButton(
// icon: Icon(Icons.message,
// color: Colors.white),
// onPressed: null),
// Text(
// 'Message',
// style: klistTileTitle,
// )
// ],
// ),
// Column(
// children: [
// IconButton(
// icon: FaIcon(
// FontAwesomeIcons.whatsapp,
// color: Colors.white,
// ),
// onPressed: () async {}),
// Text('Whatsapp', style: klistTileTitle)
// ],
// ),
// ],
// ),
// )
],
),
),
),
],
),
),
),
),
);
},
);
And finally this are the classes that handles what to display picture upload was success.
class ImageUploaded extends StatelessWidget {
ImageUploaded({this.uploadedFileURL});
final String uploadedFileURL;
#override
Widget build(BuildContext context) {
return CircleAvatar(
radius: 80,
child: ClipOval(
child: uploadedFileURL != null
? Image.network(uploadedFileURL,
height: 200, width: 200, fit: BoxFit.fill)
: Image.asset('assets/avatar_profile.jpg'),
),
);
}
}
class ImageBeforeUpload extends StatelessWidget {
ImageBeforeUpload({this.image});
final File image;
#override
Widget build(BuildContext context) {
return GestureDetector(
child: CircleAvatar(
radius: 70,
child: ClipOval(
child: image != null
? Image.asset(image.path,
height: 200, width: 200, fit: BoxFit.fill)
: Image.asset('assets/avatar_profile.jpg'),
),
),
);
}
}

Error While retrieving the number of Firebase collections in Flutter?

I'm developing an admin app in that i want to display the number of users(Collection) from the cloud firestore. When i tried doing this im able print the value in my terimal but its displaying 0 in my app.
Can someone please help in this, this my code
class _AdminState extends State<Admin> {
getUsersCount() {
var length = 0;
Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return length.toString();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.dashboard);
},
icon: Icon(
Icons.dashboard,
color: _selectedPage == Page.dashboard
? active
: notActive,
),
label: Text('Dashboard'))),
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.manage);
},
icon: Icon(
Icons.sort,
color:
_selectedPage == Page.manage ? active : notActive,
),
label: Text('Manage'))),
],
),
elevation: 0.0,
backgroundColor: Colors.white,
),
body: _loadScreen());
}
Widget _loadScreen() {
switch (_selectedPage) {
case Page.dashboard:
return Column(
children: <Widget>[
ListTile(
subtitle: Text(
'Admin View',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 29.0, color: Colors.indigo,fontWeight: FontWeight.bold),
),
),
Expanded(
child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
children: <Widget>[
Padding(
padding: const EdgeInsets.all(18.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(Icons.directions_boat,color: Colors.black,),
label: Text("Boats",style: TextStyle(fontSize: 9,color: Colors.indigo),)),
subtitle: Text(
'3',
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
Padding(
padding: const EdgeInsets.all(18.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(Icons.people,color: Colors.black,),
label: Text("Users",style: TextStyle(fontSize: 9,color: Colors.indigo),)),
subtitle: Text(
getUsersCount(),
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
Padding(
padding: const EdgeInsets.all(22.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(Icons.bookmark,color: Colors.black,),
label: Text("Bookings",style: TextStyle(fontSize: 8,color: Colors.indigo),)),
subtitle: Text(
'120',
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
],
),
),
],
);
break;
My terminal is printing the exact value which is available in the database.the terminal looks like this
My screenshot of the app looks like this
Padding(
padding: const EdgeInsets.all(18.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(Icons.people,color: Colors.black,),
label: Text("Users",style: TextStyle(fontSize: 9,color: Colors.indigo),)),
subtitle: Text(
getUsersCount(),
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
getDocuments() is asychronous, then you need to return a value of type Future to be able to get the returned value later:
Future<String> getUsersCount() {
var length = 0;
Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return Future.value(length.toString());
}
Then when you call it, you can do:
getUsersCount().then((value){
print(value);
});

Error while returning the number of count of collections in firebase flutter?

i'm developing an admin app in that i'm tired to return the number of users from firebase, i got few help from stackoverflow and was able to print in the terminal but its returning null on the app can someone please help me.this my code
class _AdminState extends State<Admin> {
Future<String> getUsersCount() async{
var length = -1;
await Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return Future.value(length.toString());
}
Page _selectedPage = Page.dashboard;
MaterialColor active = Colors.indigo;
MaterialColor notActive = Colors.grey;
final databaseReference = Firestore.instance;
bool isDelete= true;
var values;
TextEditingController categoryController = TextEditingController();
TextEditingController brandController = TextEditingController();
GlobalKey<FormState> _categoryFormKey = GlobalKey();
//GlobalKey<FormState> _brandFormKey = GlobalKey();
// BrandService _brandService = BrandService();
CategoryService _categoryService = CategoryService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.dashboard);
},
icon: Icon(
Icons.dashboard,
color: _selectedPage == Page.dashboard
? active
: notActive,
),
label: Text('Dashboard'))),
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.manage);
},
icon: Icon(
Icons.sort,
color:
_selectedPage == Page.manage ? active : notActive,
),
label: Text('Manage'))),
],
),
elevation: 0.0,
backgroundColor: Colors.white,
),
body: _loadScreen());
}
Widget _loadScreen() {
switch (_selectedPage) {
case Page.dashboard:
return FutureBuilder(
future: getUsersCount(),
builder: (BuildContext context, AsyncSnapshot<String> text) {
print(text);
if(text== "-1"){
return CircularProgressIndicator();
} else {
return Column(
children: <Widget>[
ListTile(
subtitle: Text('Admin View', textAlign: TextAlign.center,
style: TextStyle(fontSize: 29.0,
color: Colors.indigo,
fontWeight: FontWeight.bold),),
),
Expanded(child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,),
children: <Widget>[
Padding(
padding: const EdgeInsets.all(18.0), child: Card(
child: ListTile(title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.directions_boat, color: Colors.black,),
label: Text("Boats", style: TextStyle(
fontSize: 9, color: Colors.indigo),)),
subtitle: Text('3', textAlign: TextAlign.center,
style: TextStyle(
color: active, fontSize: 50.0),)),
),
),
Padding(padding: const EdgeInsets.all(18.0),
child: Card(child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.people, color: Colors.black,),
label: Text("Users", style: TextStyle(
fontSize: 9, color: Colors.indigo),)),
subtitle: Text(text.data != null ? text.data : '',
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
Padding(
padding: const EdgeInsets.all(22.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.bookmark, color: Colors.black,),
label: Text("Bookings", style: TextStyle(
fontSize: 8, color: Colors.indigo),)),
subtitle: Text(
'120',
textAlign: TextAlign.center,
style: TextStyle(
color: active, fontSize: 50.0),
)),
),
),
],
),
),
],
);
} })
i was returning a null string value but when include this set of lines Text(text.data??'default value') i was able to clear that error but still not able to clear my issue someone please help me
You need to add await before getting data from Firestore, since it is and async and you are not waiting for the result and returning the value which is initialized to 0
Future<String> getUsersCount() async {
var length = 0;
await Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return Future.value(length.toString());
}
As you can see the value of users count(36) is getting printed but it is not return because the return gets called before the async execution is getting finish..
Initialize your length to -1 in getUsersCount method and then in build method before returning the cloumn widget check the text (snapshot value) :
if (text == "-1"){
return Center(
child: CircularProgressIndicator(backgroundColor: Colors.red,)
);
} else{
return Column(....)
}

Resources