Related
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
Im trying to show a listviewbuilder with 3 text widgets. But the last text widget don't looks good. Heres how it looks
And heres my code
#override
Widget build(BuildContext context) {
final user = Provider.of<Userforid>(context);
if (nosuerfound == true) {
return ListView.builder(
itemCount: _resultsList.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 10),
child: ListTile(
onTap: () {
DatbaseService.instance
.createorGetConversation(user.uid, _resultsList[index].id,
(String _conversationID) {
/* NavigationService.instance.navigateToRoute(
MaterialPageRoute(builder: (context) {
return MeineBeitraege(
_conversationID,
_resultsList[index].id,
_resultsList[index].data()['username'],
);
}),
);*/
});
},
leading: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
child: Text(
_resultsList[index].data()['hashtag1'],
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20.0,
),
),
),
),
Expanded(
child: Container(
child: Text(
_resultsList[index].data()['hashtag2'],
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20.0,
),
),
),
),
Expanded(
child: Container(
child: Text(
_resultsList[index].data()['hashtag3'],
style: const TextStyle(
// fontWeight: FontWeight.w500,
fontSize: 20.0,
),
),
),
),
],
),
// subtitle: Text(_resultsList[index].data()['email']),
),
);
});
} else {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Container(
child: Text(
"No Hashtag found",
style: TextStyle(fontSize: 16),
)),
);
}
}
}
So what I want is getting a bit padding between every text widget inside column. And also the last hashtag should be showed correctly . Not showed half .Hope anyone can help .if you need more informations please leave a comment .
You don't need use ListTile for show three elements in trailing, use custom widget or simple Container with Gesture Detector (or InkWell for the material tap effect).
It is not necessary either the Expanded Widget.
ListView.builder(
itemCount: _resultsList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 10),
margin: const EdgeInsets.all(10.0), // Add margin
child: InkWell(
onTap: () {
/*DatbaseService.instance
.createorGetConversation(user.uid, _resultsList[index].id,
(String _conversationID) {
/* NavigationService.instance.navigateToRoute(
MaterialPageRoute(builder: (context) {
return MeineBeitraege(
_conversationID,
_resultsList[index].id,
_resultsList[index].data()['username'],
);
}),
);*/
});*/
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_resultsList[index].data()['hashtag1'],
'Text 1',
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 15.0,
),
),
Text(
_resultsList[index].data()['hashtag2'],
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 15.0,
),
),
Text(
_resultsList[index].data()['hashtag3'],
style: const TextStyle(
// fontWeight: FontWeight.w500,
fontSize: 15.0,
),
),
],
),
),
);
},
),
I am holding a counter in my Firebase which holds the total upvotes for a picture. When the upvote button is pressed, the database should update the counter of that specified counter by 1, which it does. However, it doesn't show the update on the app screen. For example if an image has 8 upvotes, and the button is pressed to upvote, it will still show 8 upvotes on the screen but in the database it will now be 9 upvotes. When I hot refresh the value changes. How can I make both things happen asynchronously? I tried playing around with it and it's always that either it updates the database and the screen stays unchanged, or the screen changes and the database doesn't.
For the functions below, they behave as expected but just not asynchronously on the screen.
The relevant function that increments the followers in the database:
// likedposts is a list of posts that have already been liked and is initalised earlier
// even if I remove the if statement here, the behaviour is the same
void incrementFollowers(int index) async {
if (!likedposts.contains(posts[index])) {
likedposts.add(posts[index]);
addLikedPost();
FirebaseFirestore.instance
.collection('uploads')
.doc(usernames[index])
.collection('images')
.where('caption', isEqualTo: captions[index])
.get()
.then((querySnapshot) {
querySnapshot.docs.forEach((result) async {
FirebaseFirestore.instance
.collection('uploads')
.doc(usernames[index])
.collection('images')
.doc(result.id)
.update({'upvotes': upvotes[index]+1,});
setState(() {
getUpvotes(index);
});
});
});
}
}
The function that displays the upvotes:
getUpvotes(int index) {
return RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: upvotes[index].toString() + ' upvotes',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
print(
'This will take to upvoters of the photo');
}),
]));
}
The widget that displays everything in my app (to find where I'm calling the incrementFollowers button, just do ctrl+F for incrementFollowers and you'll find it):
Widget _getPost() {
Size size = MediaQuery.of(context).size;
if (url!= null) {
return new ListView.builder(
itemCount: images.length,
itemBuilder: (BuildContext context, int userIndex) {
return Container(
child: Column(
children: <Widget>[
Container(
//Includes dp + username + report flag
margin: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 8),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
},
child: CircleAvatar(
backgroundImage: displayPic[1],
))),
RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: usernames[userIndex],
style: TextStyle(
color: Colors.black, fontSize: 15.0),
recognizer: TapGestureRecognizer()
..onTap = () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
})
]),
)
],
),
IconButton(
icon: Image.asset('assets/pictures/ICON_flag.png'),
iconSize: 25,
onPressed: () {
reportUser(userIndex, context);
},
),
],
),
),
Stack(children: <Widget>[
Container(
//the post picture
child: GestureDetector(
//This is to handle the tagged users raised button
onTap: () {
if (isVisible == false)
setState(() {
isVisible = true;
});
else
setState(() {
isVisible = false;
});
},
),
height: size.height * 0.5,
width: returnWidth(),
padding: EdgeInsets.only(
left: 16,
right: 16,
top: 0,
bottom: 24,
),
// constraints: BoxConstraints(maxHeight: 50),
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill, image: NetworkImage(images[userIndex])),
)
),
Positioned(
top: 25,
left: 50,
child: returnTaggedUsers(userIndex),)
]),
Row(
mainAxisAlignment: returnAlignment(),
// upvote + downvote + comment + send + save icons
children: <Widget>[
Container(
color: upVoted ? Colors.blue : Colors.white,
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_upvote.png'),
iconSize: 25,
onPressed: () async {
setState(() {
incrementFollowers(userIndex);
});
getUpvotes(userIndex);
},
)
),
Container(
color: downVoted ? Colors.blue : Colors.white,
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_downvote.png'),
iconSize: 25,
onPressed: () {
setState(() {
downVoted = true;
upVoted = false;
});
},
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_comment.png'),
iconSize: 25,
onPressed: () {
commentPopUp(userIndex, context);
},
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON-send.png'),
iconSize: 25,
onPressed: () {
print(
'This will let a user send the post to another user');
},
)),
Container(
margin: EdgeInsets.only(right: 8),
child: IconButton(
icon: Image.asset('assets/pictures/ICON_save.png'),
iconSize: 25,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ReportPanel()
),
);
},
)),
],
),
Column(
mainAxisAlignment: returnAlignment(),
//This column contains username, upload description and total upvotes
children: <Widget>[
Container(
//The person who posted along with photo description
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: usernames[userIndex] + ': ',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserProfile(usernames[userIndex])
),
);
}),
TextSpan(text: captions[userIndex]),
])),
),
Container(
//The total upvotes of post
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: getUpvotes(userIndex),
)
],
),
Column(
mainAxisAlignment: returnAlignment(),
//This column contains username and comment of commenters
children: <Widget>[
Container(
//First comment
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'HarperEvans1: ', //will be a username from firebase
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
print(
'This will take to profile of that person');
}),
TextSpan(text: 'Nice photo!'),
])),
),
Container(
//Second comment
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'trevorwilkinson: ', //will be a username from firebase
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
print(
'This will take to profile of that person');
}),
TextSpan(
text:
'Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda Panda'),
])),
),
Container(
//view more comments
alignment: returnCommentAlignment(),
margin: EdgeInsets.only(left: 10, right: 10),
child: RichText(
text: TextSpan(
style:
TextStyle(color: Colors.grey, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text:
'view more comments', //will take to the comments
style: TextStyle(color: Colors.grey),
recognizer: TapGestureRecognizer()
..onTap = () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CommentPage(posts[userIndex], usernames[userIndex])
),
);
}),
])),
)
],
)
],
));
});
}
}
Thank you!
Currently you have nothing triggering a rebuild from Firebase. You need to return a FutureBuilder or StreamBuilder in your getUpvotes function. That will get notified of changes in the cloud and trigger a re-build.
Here's something to get you started. Return this instead in your getUpvotes method and complete the stream portion of the StreamBuilder
StreamBuilder(
stream: Firestore.instance.collection...// finish this part to get your snapshot of total upvotes from your collection,
builder: (context, snapshot) {
if(snapshot.hasData) {
return RichText(
text: TextSpan(
style: TextStyle(color: Colors.black, fontSize: 20.0),
children: <TextSpan>[
TextSpan(
text: upvotes[index].toString() + ' upvotes',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () {
print('This will take to upvoters of the photo');
}),
],
),
);
}
else {
// handle no data
}
},
);
My every textfield is getting validated. But if the image is not selected and I press submit. It successfully gets uploaded to firestore without an image. But I want to make it stop incase image is null. When i load image it gets display in buildGridView. I guess i need to apply logic somewhere here. That if buildGridView is null. Stop or something. How can i achieve it. Thanks
Widget AddPost() {
return Form(
key: _key,
autovalidate: _validate,
child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
child: Column(
children: <Widget>[
_getPropertyTypeDropDown(),
_getPropertyTypeDetailDropDown(),
UploadPropertyImages(),
Container(
margin: EdgeInsets.only(left: 7),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
width: 200,
height: MediaQuery.of(context).size.height / 4,
//color: Colors.green,
child: buildGridView(),
),
RaisedButton(
child: Text("Submit"),
onPressed: () async {
if (_key.currentState.validate()) {
_key.currentState.save();
Alert(
context: context,
style: alertStyle,
type: AlertType.info,
title: "YEY !!",
desc: "Your Ad will be displayed soon.",
buttons: [
DialogButton(
child: Text(
"Thankyou",
style: TextStyle(color: Colors.white, fontSize: 20),
),
// onPressed: () => Navigator.pop(context),
color: Color.fromRGBO(0, 179, 134, 1.0),
radius: BorderRadius.circular(0.0),
),
],
).show();
await runMyFutureGetImagesReference();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RoleCheck()));
} else {
setState(() {
_validate = true;
});
}
},
textColor: Colors.black,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
splashColor: Colors.grey,
),
],
),
),
//_showSubmitButton(),
],
)),
);
}
Widget buildGridView() {
return GridView.count(
crossAxisCount: 3,
children: List.generate(images.length, (index) {
Asset asset = images[index];
print(asset.getByteData(quality: 100));
return Padding(
padding: EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent, width: 2)),
child: AssetThumb(
asset: asset,
width: 300,
height: 300,
),
),
),
// ),
);
}),
);
}
Widget UploadPropertyImages() {
return Container(
child: Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
NiceButton(
width: 250,
elevation: 8.0,
radius: 52.0,
text: "Select Images",
background: Colors.blueAccent,
onPressed: () async {
List<Asset> asst = await loadAssets();
if (asst.length == 0) {
showInSnackBar("No images selected");
}
// SizedBox(height: 10,);
else {
showInSnackBar('Images Successfully loaded');
}
}),
],
),
)));
}
Widget build(BuildContext context) {
return Scaffold(
// backgroundColor: Colors.grey[600],
key: _scaffoldKey,
body: Container(
padding: EdgeInsets.all(16.0),
child: Form(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Center(
child: Text(
"Post New Ad",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
AddPost(),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 16),
),
], //:TODO: implement upload pictures
),
),
),
);
}
Future<List<Asset>> loadAssets() async {
List<Asset> resultList = List<Asset>();
String error = "No error Detected";
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 10,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Upload Image",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
print(resultList.length.toString() + "it is result list");
/* print((await resultList[0].getThumbByteData(122, 100)));
print((await resultList[0].getByteData()));
print((await resultList[0].metadata));*/
print("loadAssets is called");
} on Exception catch (e) {
error = e.toString();
print(error.toString() + "on catch of load assest");
}
By default Image Picker field is not a form element. You can pick a plugin to do so for your application. Here I am adding one. Please include it and it will give you the scope to validate the picked image as your requirements.
https://pub.dev/packages/image_picker_form_field
You will have to include it in pubspec.yaml and you are ready to use the widget it provides. Just use that like below:
ImagePickerFormField(
child: Container(
height: 40,
child: Center(child: Text("Select Photo")),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
border: Border.all(
color: Theme.of(context).disabledColor, width: 1)),
),
previewEnabled: true,
autovalidate: true,
context: context,
onSaved: (File value) {
print("on saved called");
},
validator: (File value) {
if (value == null)
return "Please select a photo!";
else return null; },
initialValue: null, //File("some source")
)
The issue here is that when I fetch the data, I am suppose to fetch it for the current user but it is rather fetching data for all users within that collection.
I have done reading and watched a number of videos for a possible solution but I can't seem to find how to do this. Your help is needed please. Thanks.
A excerpt of the bode is below.
File image;
TextEditingController loginNameController = TextEditingController();
TextEditingController loginPhoneController = TextEditingController();
TextEditingController loginAddressController = TextEditingController();
clearForm() {
setState(() {
image = null;
loginNameController.clear();
loginPhoneController.clear();
loginAddressController.clear();
});
}
//=====> FOR INSTANCES OF FIREBASE <=====
final auth = FirebaseAuth.instance;
final db = FirebaseFirestore.instance;
User user = FirebaseAuth.instance.currentUser;
body: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: StreamBuilder(
stream: db.collection("collection name").snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if (!snapshot.hasData) {
return Center(
child: spinkit,
);
}
return ListView.builder (
itemCount: snapshot.data.docs.length,
itemBuilder: (BuildContext context, int index){
return Stack(
children: [
Column(
children: [
Stack(
children: [
// ===> RETRIEVING USER DETAILS AND SHOWING IT IN A ROW <===
Container(
padding : EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
backgroundColor: Palette.mainColor,
radius: 50,
child: ClipOval(
child: SizedBox(
height: 150,
width: 150,
child: image == null ? Center(
// child: Image.asset("asset/images/placeholder.png", fit: BoxFit.cover,),
child: Image.network(snapshot.data.documents[index].get("image")),
):
Image.file(image, fit: BoxFit.cover,),
),
),
),
SizedBox(width: 16,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 0),
child: Text(snapshot.data.documents[index].get("Name"),
style: TextStyle(
letterSpacing: 2,
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.bold,
),),
),
SizedBox(height: 5,),
Text(snapshot.data.documents[index].get("Address"),
style: TextStyle(
letterSpacing: 2,
color: Colors.black54,
fontSize: 16,
),),
SizedBox(height: 5,),
Text(snapshot.data.documents[index].get("Number"),
style: TextStyle(
letterSpacing: 2,
color: Colors.black54,
fontSize: 16,
),),
],
),
),
Padding(
padding: EdgeInsets.only(left: 0, bottom: 15),
child: IconButton(
icon:Icon(Icons.edit, color: Palette.mainColor, ),
onPressed: () { },
),
),
],
),
),
],
),
],
),
],
);
},
);
},
),
)
The collection name is members
Try like this, stream of your widget should be like this, as said above.
db.collection("Users").document(user.uid).snapshots();
for length in Listview.builder, change it too
snapshot.data.length;
And last, All the data which you fetch data like this should change into
from:
snapshot.data.documents[index].get("image")
To:
snapshot.data["image"]
Note I didn't test it. So, it might or might not work.
First of All use a DocumentSnapshot Shown below:
StreamBuilder<DocumentSnapshot>
Make a collection to get current user Profile data.
db.collection("Users").doc(user.uid).snapshots();
Remove ListView.builder
To get an Email Address use the below Line
Text('${streamSnapshot.data['Email Address']}'),
Here is the complete Article https://medium.com/#kamranktk807/fetch-user-data-from-firestore-and-show-them-in-profile-screen-using-flutter-609d2533e703
By the way I sol this problem with the help of a Professional Flutter Developer SHAKIR ZAHID [shakirzahid191#gmail.com].