How to retrieve an array data from firebase using flutter - firebase

hi i have an firebase as a back end for my flutter app and i can read and write data fine but i can not retrieve an array of strings when i put it in a text widget and add the .toString() parameter it retrieves it but in unpresentable way i want to view it in a list view can anybody help.
this is my code
ListView.builder(
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(5.0),
itemBuilder: (context, i) {
return new Container(
child: Padding(
padding: EdgeInsets.only(top: 5, right: 5, left: 5),
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 9,
color: Theme.of(context).cardColor.withOpacity(.95),
shadowColor:
Theme.of(context).accentColor.withOpacity(.5),
child: Container(
padding: EdgeInsets.only(
bottom: 10, right: 10, left: 10, top: 15),
height: 230,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius: BorderRadius.circular(20),
border: Border.all(
width: 1, color: Colors.grey.withOpacity(0.5))),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
'members :-' +
snapshot.data.documents[i].data['members']
.toString(),
style: TextStyle(
color: Colors.white, fontSize: 15),
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
'amount :-' +
snapshot
.data.documents[i].data['amount'],
style: TextStyle(
color: Colors.white, fontSize: 15),
),
),)

If your snapshot is not a stream then await the request and store it in a local variable. Else, Make use of a stream builder widget

Related

how to set height of gridView Builder according to Random list items we are getting

can't able to scroll how to set height of gridView Builder according to Random list items we are getting?
i want my GridView to be scrolled by SingleChildScrollView as i want to set my gridView to non Scrollable!! and set GridView's height according to the items.length(mealItem.length // given in code)
SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 14),
decoration: BoxDecoration(border: Border.all()),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(left: 14, right: 14),
child: Text(
"منتجات الالبان",
style: TextStyle(color: Colors.black, fontSize: 18),
),
),
SizedBox(height: 10),
// filter button
Container(
height: 45,
width: 351,
padding: EdgeInsets.only(left: 14, right: 14),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
color: Colors.black),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset("assets/filter.png",
height: 17, width: 16, color: Colors.white),
Text("تصنيف", style: TextStyle(color: Colors.white))
],
),
),
// over
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(right: 12),
child: Text(
"الالبان",
style: TextStyle(fontSize: 16),
),
),
SizedBox(height: 10),
// meal Item of particular category
Container(
height: MediaQuery.of(context).size.height,
child: GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 4.5,
crossAxisSpacing: 18,
mainAxisSpacing: 24,
),
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(border: Border.all()),
child: Card(
elevation: 4,
),
);
},
itemCount: mealList.length,
))
],
),
),
),

How to make Tinder like Bio editor - Flutter

I want a Tinder-like Bio editor, When the user taps on the info, the text field should appear and retrieve the data from the firebase, and display the old bio, if the user taps on the done button on the keyboard or press anywhere on the screen, the data should be submitted. Thanking you in advance
Update: Here is the code I tried, Is there any way I can remove the upper stack and show the text field when the about container is tapped and after the submission the stack to come back and display the about field, and also I want to retrieve the old text from firebase in the text field(when the user is updating).
Widget about(BuildContext context, dynamic snapshot) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Container(
height: MediaQuery
.of(context)
.size
.height * 0.2,
width: MediaQuery
.of(context)
.size
.width,
decoration: BoxDecoration(
color: constantColors.white,
borderRadius: BorderRadius.circular(15),
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(
top: 8.0,
left: 10,
),
child: Text(
"About",
style: TextStyle(fontSize: 24),
),
),
Padding(
padding: const EdgeInsets.only(top: 13, left: 6),
child: Icon(
FontAwesome.pencil,
size: 13,
),
)
],
),
Stack(
children: [
Container(
height: MediaQuery
.of(context)
.size
.height * 0.1,
width: MediaQuery
.of(context)
.size
.width,
child: TextField(
onTap: (){
Provider.of<PostFunctions>(context, listen: false).about(context, Provider.of<Authentication>(context, listen: false).getUserUid, {
'about': aboutController.text,
});
},
controller: aboutController,
maxLines: 8,
cursorColor: constantColors.green,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(15),
hintText: 'A little about you',
isDense: true,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide.none),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide.none),
fillColor: constantColors.white,
filled: true,),
),
),
Container(
height: MediaQuery
.of(context)
.size
.height * 0.1,
width: MediaQuery
.of(context)
.size
.width,
color: constantColors.white,
child: Text(snapshot.data.data()['about']),),
],
),
]),
),
);
}
here is the future method of uploading and updating
Future about(BuildContext context, String userID, dynamic data)async{
return FirebaseFirestore.instance.collection('users').doc(userID).update(data);
}
The better approach will be to retrieve the user data ahead of time. Then you can populate the text field using its conntroller with the data if the data exists.

Flutter and Firebase: Show stored information from cloud_firestore in widget

I want to show data from my firebase cloudfirestore as you see in the picture:
In a Settings page I want to show all the information from the logged-in user.
Here is the Settings-Code ("einstellungen" in german):
class einstellungen extends StatelessWidget {
final user = FirebaseAuth.instance.currentUser;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("Einstellungen"),
),
backgroundColor: Colors.orange,
body: SingleChildScrollView(
child: Column(
children: [
Container(
margin: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 10.0, bottom: 5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white.withOpacity(0.2),
),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text('Benutzer:',
style: TextStyle(fontWeight: FontWeight.bold)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(
bottom: 10.0, left: 10.0, right: 10.0),
child: Text(''),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text('Spitzname:',
style: TextStyle(fontWeight: FontWeight.bold)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(
bottom: 10.0, left: 10.0, right: 10.0),
child: Text(''),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text('E-Mail:',
style: TextStyle(fontWeight: FontWeight.bold)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(
bottom: 10.0, left: 10.0, right: 10.0),
child: Text(''), // here should print the email address from firestore
),
),
Text(''),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text('Hinweis: ',
style: TextStyle(fontWeight: FontWeight.bold)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Wenn Du dein Konto löschen oder dein Passwort zurücksetzen möchtest, schreibe bitte eine Email an medien#visuhome.de'),
),
),
Text(''),
],
)),
Container(
margin: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 3.0, bottom: 3.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white.withOpacity(0.2),
),
child: Row(
children: [
ButtonNutzung(),
Text("Nutzungsbedingungen",
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
],
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Divider(),
),
SizedBox(height: 10),
if (user.uid != null)
Text(
'Cloud User-ID: ' + user.uid,
style: TextStyle(color: Colors.black),
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.all(10.0),
child: Divider(),
),
GestureDetector(
onTap: _launchURL2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 20.0, right: 20.0),
child: Text(
'created by visuhome',
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12,
color: Colors.black),
),
),
Image(
//AssetImage oder SizedBox mit child und width
image: AssetImage('assets/visuhome_logo_black_flutter.png'),
fit: BoxFit.fitHeight,
height: 30,
),
Padding(
padding: const EdgeInsets.only(left: 20.0, right: 20.0),
child: Text(
'Version 1.0',
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12,
color: Colors.black),
),
),
],
),
),
],
),
),
);
}
}
As you can see I do get information from the FirebaseAuth.instance.currentUser, so the userid from the logged-in user is shown. But I want the information from the userdata in firestore too.
Can anybody help with this basic firestore-trick I guess? I'm new in flutter. Tried a lot but cannot find solutions which fit for my example. Thanks a lot
You should to create query to Firestore and get user details.
If you know the user ID, you can call doc function to create query.
#override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data.data();
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
},
);
}
Or use where expression to find user by its attributes (for example email):
FirebaseFirestore.instance
.collection('users')
.where('email', isEqualTo: "test#yahoo.de")
.get()
For more details check Firestore tutorial

how to connect space between Container with box shadow on flutter?

I had a problem with my project, i'm trying make container with box shadow on bottom. below that container i want make to new container but they are some separate space between container, i think its because box shadow. so the question is how to make they connect ith no space but the shadow still visible.
pic
here my code :
return Scaffold(
body: SafeArea(
child: Container(
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.zero,
topRight: Radius.zero,
),
child: Container(
height: 70.0,
margin: const EdgeInsets.only(
bottom: 6.0), //Same as `blurRadius` i guess
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5.5),
bottomRight: Radius.circular(5.5),
topLeft: Radius.zero,
topRight: Radius.zero,
),
color: kDarkGreenColor,
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
),
child: ListView.builder(
padding: EdgeInsets.only(left: 10, right: 5),
itemCount: planticos.length,
physics: BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.only(right: 15, bottom: 6),
height: 40,
width: 70,
decoration: BoxDecoration(
color: kMainColor.withOpacity(0),
image: DecorationImage(
image: AssetImage(planticos[index].image),
),
),
);
}),
),
),
),
),
Container(
margin: EdgeInsets.only(top: 0),
height: 200,
color: kMainColor,
),
],
),
),
),
);
}
use stack.
2nd Container will be visible over 1st Container.
for example...
Stack(
children: <Widget>[
Container(
height: 400,
decoration: BoxDecoration(
color: Colors.green,
),
),
Container(
height: 200,
decoration: BoxDecoration(
color: Colors.green,
boxShadow: [
BoxShadow(
color: Colors.red,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
),
),
],
),
You should use the stack widget, see this example:
Stack(
children:[
Container() //which you wanna be under the shadow.
Container() //which you wanna make it's shadow visible.
]
)
Tip: Use Positioned() under the stack to specify the position of containers.

How to hide a single item from a stream builder

Hi I have a stream builder that lists containers with a button to count down and when the counter hits zero I wanted to hide that single container from the list I can’t figure out how to, if anyone does please help
bool visibility = true;
Widget _dataList() {
if (data != null) {
return StreamBuilder(
stream: data,
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(5.0),
itemBuilder: (context, i) {
return visibility == true
? new Container(
child: Padding(
padding: EdgeInsets.only(top: 5, right: 5, left: 5),
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 9,
color:
Theme.of(context).cardColor.withOpacity(.95),
shadowColor:
Theme.of(context).accentColor.withOpacity(.5),
child: Container(
padding: EdgeInsets.only(
bottom: 10, right: 10, left: 10, top: 15),
height: 210,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius: BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey.withOpacity(0.5))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
'Number Of Participants :-' +
snapshot.data.documents[i]
.data['numberOfParticipants'],
style: TextStyle(
color: Colors.white, fontSize: 15),
),
),
Padding(
padding: const EdgeInsets.only(top: 7.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
borderRadius:
BorderRadius.circular(20),
elevation: 26,
color: Color(0xFF0B0F1B),
child: Container(
height: 30,
width: 120,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius:
BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey
.withOpacity(0.5))),
child: InkWell(
splashColor: Colors.redAccent,
borderRadius:
BorderRadius.circular(20),
child: Center(
child: Text(
'View',
style: TextStyle(
color: Color(0xFFC77AF3),
fontSize: 18),
)),
onTap: () {
int currentval = int.parse(
snapshot.data.documents[i]
.data[
'numberOfParticipants']);
setState(
() {
currentval--;
snapshot.data.documents[i]
.data[
'numberOfParticipants'] =
currentval.toString();
if (currentval == 0) {
visibility = false;
}
},
);
},
),
),
),
SizedBox(
width: 85,
),
Material(
borderRadius:
BorderRadius.circular(20),
elevation: 26,
color: Color(0xFF0B0F1B),
child: Container(
height: 30,
width: 120,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius:
BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey
.withOpacity(0.5))),
child: InkWell(
splashColor: Colors.greenAccent,
borderRadius:
BorderRadius.circular(20),
child: Center(
child: Text(
'Join',
style: TextStyle(
color: Colors.greenAccent,
fontSize: 18),
)),
onTap: () {
setState(
() {},
);
},
),
),
),
],
),
),
],
),
),
),
),
)
: new Container();
},
);
});
} else {
return Center(child: Text('Nothing yet'));
}
}
this is my code i tried to accomplish the visibility by an empty container because i don't want it to hold a place but the problem is it hides all other containers with it the whole list goes invisible
You can use Opacity with an opacity: of 0.0 to draw make an element hidden but still occupy space.
To make it not occupy space, replace it with an empty Container().
EDIT: To wrap it in an Opacity object, do the following:
new Opacity(opacity: 0.0, child: new Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: new Icon(pencil, color: CupertinoColors.activeBlue),
))
Google Developers quick tutorial on Opacity: https://youtu.be/9hltevOHQBw
you can also try
Visibility(
visible: false,
child: child
)
);

Resources