Flutter - How can I save the selected index of DropDownMenu to FireStore when the form is submitted - firebase

Here is my code for the dropdown list
Container(
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
//border: ,
borderRadius: BorderRadius.circular(20),
),
//color: Colors.white,
margin:
EdgeInsets.only(left: 50, right: 50),
child: StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection("Choose Platform")
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData)
const Text("Loading.....");
else {
List<DropdownMenuItem>
chooseplatform = [];
for (int i = 0;
i <
snapshot.data.documents
.length;
i++) {
DocumentSnapshot snap =
snapshot.data.documents[i];
chooseplatform.add(
DropdownMenuItem(
child: Text(
snap.documentID,
style: TextStyle(
color: Colors.black),
),
value: "${snap.documentID}",
),
);
}
return Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
DropdownButton(
items: chooseplatform,
onChanged:
(choosingplatform) {
final snackBar = SnackBar(
content: Text(
'Selected Platform is $choosingplatform',
style: TextStyle(
color: Color(
0xff1ffcb7)),
),
);
Scaffold.of(context)
.showSnackBar(
snackBar);
setState(() {
chosenPlatform =
choosingplatform;
});
},
value: chosenPlatform,
isExpanded: false,
hint: new Text(
"Choose Platform",
style: TextStyle(
color: Colors.black),
),
),
],
);
}
})),
And this is the code for the Raised button
RaisedButton(
padding:
EdgeInsets.only(left: 10, right: 10),
onPressed: () async {
Firestore.instance.runTransaction(
(Transaction transaction) async {
final CollectionReference reference =
Firestore.instance
.collection('Tournaments');
await reference
.document('Fifa Tournaments')
.collection('Fifa Tourneys')
.add({
'tourneyname':
tourneynameController.text,
'tourneygame':
tourneydateController.text,
});
tourneynameController.clear();
tourneydateController.clear();
});
Navigator.of(context).pop();
},
child: Text(
'Create Tournament',
style: TextStyle(fontSize: 16),
),
color: const Color(0xff1ffcb7),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(18.0),
side: BorderSide(color: Colors.white),
),
),
Right now, I can only save the values for my TextFormFields and not the Drop down list.
In a nutshell, what i'm doing right now is retrieving values from a collection and displaying them in a dropdownmenu, but what i want to do is retrieve the values then save the selected value in another collection called 'Fifa tourneys' when the form is submitted.
Thanks!

Solved!
All i had to do was save the variable for the the selectedIndex to my firestore collection.
onPressed: () async {
Firestore.instance.runTransaction(
(Transaction transaction) async {
final CollectionReference reference =
Firestore.instance
.collection('Tournaments');
await reference
.document('Fifa Tournaments')
.collection('Fifa Tourneys')
.add({
'tourneyname':
tourneynameController.text,
'tourneygame':
tourneydateController.text,
'tourneyplatform': chosenPlatform,// this is the one
});
tourneynameController.clear();
tourneydateController.clear();
chosenPlatform.clear();
});
Navigator.of(context).pop();
},

Related

Is there a way to compare two list and check for the value that are the same

I am create a social media type app I want to create a follower and following list like Instagram, I want when I go on some else profile and click on their followers or following list it shows a list of all the users that is following that person and if I am also following someone in the list it give me the option to unfollow that person and if I am not following the same person it gives me the option to follow them.
The code below is what I was to check if I am following any one in profile user followers list, What I have done is I query the data from firestore of all the user id the I am following and the same for user profile that is currently open and store the list in two separate variable and what it should do is check both list and if a user Id is in both list it means I am also following that user and should show that I am following that user and give the option to unfollow but what happens is instead of showing that I am only following the user who's id is in both list it show that I am following every one.
checkfollowers(BuildContext context, String? id) async {
final auth = Provider.of<AuthState>(context, listen: false);
List<String> followingList = [];
List<String> myFollowingList = [];
try {
final QuerySnapshot following = await _firestore
.collection('following')
.doc(auth.getCurrentUser.uid)
.collection('userFollowing')
.get();
QuerySnapshot userfollowing = await _firestore
.collection('followers')
.doc(id)
.collection('userFollowers')
.get();
following.docs.forEach((element) {
myFollowingList.add(element.id);
});
userfollowing.docs.forEach((element) {
followingList.add(element.id);
});
// followingList.where((item) => myFollowingList.contains(item));
check(value) => myFollowingList.contains(value);
isFollowedByMe = followingList.any(check);
notifyListeners();
print(followingList);
print(myFollowingList);
} catch (err) {
print(err.toString() + 'this error is coming from profileState');
}
}
below code is how I build the follower/following list
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
UserModel? users;
#override
void initState() {
final profileState = Provider.of<ProfileState>(context, listen: false);
profileState.checkfollowers(context, widget.proFileId);
super.initState();
}
userComponent(UserModel? model, BuildContext context) {
final profileState = Provider.of<ProfileState>(context);
final auth = Provider.of<AuthState>(context);
return Container(
margin: EdgeInsets.symmetric(horizontal: 10),
padding: EdgeInsets.only(top: 10, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProfilePage(profileId: '${model?.userId}'),
),
);
},
child: Row(
children: [
Container(
width: 60,
height: 60,
child: CircleAvatar(
radius: 50,
backgroundImage: NetworkImage('${model?.profilePic}'),
),
),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text('${model?.userName}',
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.w500)),
SizedBox(
height: 5,
),
Text(
'${model?.displayName}',
style: TextStyle(
color: Colors.grey[500],
),
),
],
)
],
),
),
auth.getCurrentUser.uid == model?.userId
? Container()
: GestureDetector(
onTap: () {
if (auth.getCurrentUser.uid == model?.userId) {
print('you can not follow your self');
} else if (profileState.isFollowedByMe == true) {
profileState.setIsFollowedByMeToFalse();
profileState.handleUnFollow(context, model?.userId);
} else if (profileState.isFollowedByMe == false) {
profileState.setIsFollowedByMeToTrue();
profileState.handleFollow(context, model?.userId);
}
},
child: AnimatedContainer(
height: 35,
width: 110,
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
color: profileState.isFollowedByMe == true
? AppColors.white
: AppColors.pinkaccent,
borderRadius: BorderRadius.circular(5),
border: Border.all(
color: Colors.grey.shade700,
),
),
child: Center(
child: Text(
profileState.isFollowedByMe == true
? 'UnFollow'
: 'Follow',
style: TextStyle(
color: profileState.isFollowedByMe == true
? Colors.black
: Colors.white),
),
),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
title: Container(
height: 38,
child: TextField(
onChanged: (value) {},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: EdgeInsets.all(0),
prefixIcon: Icon(
Icons.search,
color: Colors.grey.shade500,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: BorderSide.none),
hintStyle: TextStyle(fontSize: 14, color: Colors.grey.shade500),
hintText: "Search users"),
),
),
),
body: StreamListWrapper(
stream: _firestore
.collection('followers')
.doc(widget.proFileId)
.collection('userFollowers')
.snapshots(),
itemBuilder: (context, DocumentSnapshot snapshot) {
var data = snapshot.data() as Map<String, dynamic>;
users = UserModel.fromJson(data);
return userComponent(users, context);
},
text: '${widget.user?.userName} as no Followers',
),
);
It would be simpler (and more performant) to use the Set data structure rather than List. The intersection method on Set returns the items contained in both sets.
for example:
void main() {
Set<String> followingSet = {'Jeff', 'Mike', 'Joe', 'Jess'};
Set<String> myFollowingSet = {'Jess', 'Matt', 'Mike', 'Frank'};
Set<String> usersInBothSets = followingSet.intersection(myFollowingSet);
print(usersInBothSets); // {Mike, Jess}
}

How to update and delete a data in a list according to it's document id - flutter, firebase 2021

I am trying to delete and update a list of details in flutter. For that i used doc('document_id') which was given as a solution in another stackoverflow question. I tried some another solutions given in stacker flow too. But nothing fork for me. But if I give a specific documentID I am able to delete that. Also how can I pass the selected data to update page too.
class addressProfile extends StatefulWidget {
const addressProfile({Key? key}) : super(key: key);
#override
_addressProfileState createState() => _addressProfileState();
}
class _addressProfileState extends State<addressProfile> {
var Default = 'unDefault';
delete() async {
try {
FirebaseFirestore.instance
.collection("address")
.doc('document_id')
.delete();
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade100,
appBar: AppBar(
centerTitle: true,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
title: Text(
'My Addresses',
style: TextStyle(color: Colors.black),
),
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black,
),
onPressed: () {
Navigator.of(context).pushNamed('/profilePage');
},
),
),
body: ListView(
padding: EdgeInsets.all(16),
children: [
StreamBuilder<QuerySnapshot>(
stream:
FirebaseFirestore.instance.collection("address").snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Expanded(
child: SizedBox(
height: 700,
child: ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
QueryDocumentSnapshot x = snapshot.data!.docs[index];
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(x['firstName']),
Text(' '),
Text(x['lastName']),
],
),
Text(""),
Row(
children: [
Text(x['primaryPhone']),
Text(" / "),
Text(x['secondaryPhone']),
],
),
Text(''),
Row(
children: [
Text(x['address1']),
Text(', '),
Text(x['address2']),
Text(', '),
Text(x['city']),
Text(', '),
Text(x['region']),
],
),
Divider(
color: Colors.black,
),
Row(
children: [
Container(
child: Radio(
value: 'default',
groupValue: Default,
onChanged: (String? val) {
setState(() {
if (val != null)
Default = val;
});
}),
),
Container(
child: Text("Default"),
),
Container(
padding: EdgeInsets.only(left: 60),
child: Align(
child: ElevatedButton.icon(
onPressed: () {
if (snapshot.data!.docs.length >
1) {
delete();
Fluttertoast.showToast(
msg:
"Address deleted successfully",
toastLength:
Toast.LENGTH_SHORT,
gravity:
ToastGravity.BOTTOM,
textColor: Colors.black,
backgroundColor:
Colors.green.shade400,
);
} else {
Fluttertoast.showToast(
msg:
"Main address cannot be deleted",
toastLength:
Toast.LENGTH_SHORT,
gravity:
ToastGravity.BOTTOM,
textColor: Colors.black,
backgroundColor:
Colors.green.shade400,
);
}
},
label: Text('Delete'),
style: ElevatedButton.styleFrom(
fixedSize: Size(90, 20),
primary: Colors.red.shade500,
padding: EdgeInsets.symmetric(
horizontal: 5,
),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
10))),
icon: Icon(
Icons.delete_outline_sharp),
),
),
),
Container(
padding: EdgeInsets.only(left: 14),
child: Align(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) =>
updateAddress(),
),
);
},
label: Text('Update'),
style: ElevatedButton.styleFrom(
fixedSize: Size(90, 20),
primary:
Colors.green.shade500,
padding: EdgeInsets.symmetric(
horizontal: 5,
),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
10))),
icon: Icon(Icons.edit),
),
),
),
],
),
],
),
),
),
);
},
),
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}),
Align(
alignment: AlignmentDirectional.bottomCenter,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/addNewAddress');
},
child: Text(
"Add New Address",
style: TextStyle(
fontSize: 15,
letterSpacing: 2,
color: Colors.black,
),
),
style: ElevatedButton.styleFrom(
fixedSize: Size(250, 40),
primary: Colors.green.shade500,
padding: EdgeInsets.symmetric(
horizontal: 50,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10))),
),
),
],
),
);
}
}
This is so far I did. Please help me to continue.
I don't know how you have saved the data. But I got an issue like this and what I did was, I added a variable as "id" to database while saving the data. There is an auto generated id plugin for flutter (nanoid). You can add that and save the data as following.
var id = nanoid(10) //10 is the length of the id. You can give as you wish
create() async {
try {
FirebaseFirestore.instance
.collection("address")
.doc(id)
.set({
"id":id,
//other inputs
});
} catch (e) {
print(e);
}
}
Then you can use that id as a key to update ad delete.
For example according to you code to delete you can use like this in the onPress(){} of delete button,
FirebaseFirestore.instance.collection("address").doc(x['id']).delete();
So the data related to id will be deleted.
Also better to use proper name rather than "x".
Can you please try this
delete(String docId) async {
try {
FirebaseFirestore.instance
.collection("address")
.doc(docId)
.delete();
} catch (e) {
print(e);
}
}
Your delete function call
delete(snapshot.data!.docs[index].id);
Update document
void update(String docId){
FirebaseFirestore.instance.collection("address").doc(docId) .update({"field1":"fieldValue1","field2":"fieldValue2"});
}
Let me know if you find any issues in comment

type 'Future<dynamic>' is not a subtype of type 'Widget?'

IM trying to call on Tap method, what I want now is change it to a future method because on Tap the method is not ready because im calling a firebase query . So heres first my method
where the onTap function is
child: InkWell(
onTap: () async {
setState(() {
israting = true;
});
},
child: israting
? buildBody(videos.data()['likes'], videos.data()['id'])
: Icon(
Icons.star,
size: 37,
color: videos.data()['likes'].contains(uid)
? Colors.yellow
: Colors.white,
),
),
So im giving the buildBody 2 parameters from a streambuilder
and then thats the function
buildBody(videoid, video) async {
if (videoid.contains(uid)) {
await FirebaseFirestore.instance
.collection("videos")
.doc(video)
.collection("uservotes")
.doc(uid)
.get()
.then((value) {
votefromfirebase = value.data()["rating"];
});
return Container(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(3, 7, 0, 0),
child: Align(
alignment: Alignment.topLeft,
child: RatingBarIndicator(
rating: votefromfirebase,
itemBuilder: (context, index) => InkWell(
child: Icon(
Icons.star,
color: Colors.amber,
),
),
itemCount: 5,
itemSize: 31.0,
direction: Axis.horizontal,
),
),
),
Align(
alignment: Alignment.topRight,
child: TextButton(
onPressed: () {
print(video);
letuservoting = true;
setState(() {
_userRating = 0.0;
israting = false;
});
dislike(idovvideo, _userRating);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
],
));
} else {
return Container(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(3, 7, 0, 0),
child: Align(
alignment: Alignment.topLeft,
child: RatingBarIndicator(
rating: _userRating,
itemBuilder: (context, index) => InkWell(
onTap: () {
setState(() {
_userRating = index + 1.toDouble();
});
likevideo(video, _userRating);
},
child: Icon(
Icons.star,
color: Colors.amber,
),
),
itemCount: 5,
itemSize: 31.0,
direction: Axis.horizontal,
),
),
),
Align(
alignment: Alignment.topRight,
child: TextButton(
onPressed: () {
letuservoting = true;
setState(() {
_userRating = 0.0;
israting = false;
});
dislike(idovvideo, _userRating);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
],
),
);
}
}
buildprofile(String url) {
return Container(
width: 50,
height: 50,
child: Stack(
children: [
Positioned(
left: (50 / 2) - (50 / 2),
child: Container(
width: 50,
height: 50,
padding: EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
),
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(60),
child: Container(
height: 110,
width: 110,
decoration: BoxDecoration(
color: Colors.white,
),
child: url != null && url != "profilepictureer"
? Image.network(
url,
fit: BoxFit.cover,
)
: Image.asset(
'assets/profilepictureer.png') // Your widget is here when image is no available.
),
),
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: new Border.all(color: Colors.black, width: 4)),
),
),
),
],
),
);
}
}
At the moment im getting this error
The following _TypeError was thrown building:
type 'Future<dynamic>' is not a subtype of type 'Widget?'
When the exception was thrown, this was the stack
#0 _VideopageofcurrentuserState.build.<anonymous closure>.<anonymous closure> (package:wichtigdenyady/taking%20videos/currentuservideos.dart:310:47)
#1 SliverChildBuilderDelegate.build
package:flutter/…/widgets/sliver.dart:455
#2 SliverMultiBoxAdaptorElement._build
package:flutter/…/widgets/sliver.dart:1201
#3 SliverMultiBoxAdaptorElement.performRebuild.processElement
package:flutter/…/widgets/sliver.dart:1145
#4 Iterable.forEach (dart:core/iterable.dart:257:30)
The error throws in the onTap function
The buildBody function cannot be an async function.
You should move the call to Firebase out of this function and use the result of it in state, instead.
An async function always returns a Future. Because the return type isn't defined, it assumes it will return a Future<dynamic>. If you defined the return type as Widget buildBody(videoid, video) async, the IDE would show an error.
In your onTap function, you can make the call:
onTap: () async {
setState(() {
israting = true;
});
if(!videos.data()['likes'].contains(uid)) return; // don't call firebase if uid is not in videoid
final value = await FirebaseFirestore.instance
.collection("videos")
.doc(video)
.collection("uservotes")
.doc(uid)
.get();
setState(() {
votefromfirebase = value.data()["rating"];
});
},
Next, change the buildBody function to a non-async function and check if votefromfirebase is in the state
Widget buildBody(videoid, video) {
if (votefromfirebase == null) {
return Container(); // return empty container, progress indicator, or anything else
}
// else return the normal body
return Container(
child: Stack(
// rest of this widget

how to fetch data from firestore array of a document with flutter?

this is my users collection in cloud fire store:
users collection
this is the function that gets users from users collection in firestore
Stream<QuerySnapshot> fetchUsersInSearch() {
return Firestore.instance.collection('users').snapshots();
}
i use this method
final emailResults = snapshot.data.documents
.where((u) => u['email'].contains(query));
in the following streamBuilder to fetch users by their email.
i have this streamBuilder to populate the data on screen
return StreamBuilder<QuerySnapshot>(
stream: DatabaseService().fetchUsersInSearch(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
final emailResults = snapshot.data.documents
.where((u) => u['email'].contains(query));
if (!snapshot.hasData) {
return Container(
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
'',
style: TextStyle(
fontSize: 16, color: Theme.of(context).primaryColor),
),
),
);
}
if (emailResults.length > 0) {
return Container(
color: Theme.of(context).primaryColor,
child: ListView(
children: emailResults
.map<Widget>((u) => GestureDetector(
child: Padding(
padding: const EdgeInsets.all(0.1),
child: Container(
padding: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
border: Border(
bottom: BorderSide(
width: 0.3, color: Colors.grey[50]))),
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).primaryColor,
backgroundImage:
NetworkImage(u['userAvatarUrl']),
radius: 20,
),
title: Container(
padding: EdgeInsets.only(left: 10),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(u['email'],
style: TextStyle(
fontSize: 16,
color: Theme.of(context)
.accentColor),
overflow: TextOverflow.ellipsis),
SizedBox(
height: 5,
),
],
),
),
),
),
),
onTap: () {
showUserProfile(u['id']);
},
))
.toList(),
),
);
} else {
return Container(
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
'No results found',
style: TextStyle(
fontSize: 16,
color: Theme.of(context).accentColor,
),
),
),
);
}
});
this is working perfectly and fetching users inside a listView by their email...
p.s: the (query) is a string i type in a seach bar.
how can i make a query to fetch users by their otherUsernames...the second field in the screenshot of the users collection ?!
i tried this:
final otherUsernamesResults = snapshot.data.documents
.where((u) => u['otherUsernames'].contains(query));
but its returning this error:
The method 'contains' was called on null.
Receiver: null
Tried calling: contains("#username1")
what am i doing wrong here ?!!
any help would be much appreciated..
Try this:-
Stream<QuerySnapshot> getUsers() {
final usersCollection = FirebaseFirestore.instance.collection('users');
return usersCollection.where('otherUsernames', arrayContainsAny: ['username1', 'username2']);
}
For firestore version 0.16.0

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