So I am trying to create a profile screen with 3 tabs... profile, recent and review however upon trying to do so I am facing an error. I am not able to represent all 3 tabs. Recent tab has this widget
Widget RecentItems() {
return Padding(
padding: const EdgeInsets.all(10.0),
child: StreamBuilder(
stream: Firestore.instance
.collection("users")
.document(uid)
.collection("recent")
.snapshots(),
builder: (context, snapshot) {
print(snapshot.data);
List orders = List.from(Map.from(snapshot.data.data)['orders']);
Map order;
for (int i = 0; i < orders.length; i++) {
if (orders[i]['orderId'] == widget.map['orderId'] &&
orders[i]['homemaker'] == widget.map['homemaker']) {
order = orders[i];
break;
}
}
if (snapshot.data.isEmpty) {
return Center(
child:
Text("OOPS, Looks like no one is serving!"));
}
print(order);
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
print(snapshot.data.documents[0].data);
return Container(
height: 400,
child: ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.all(10.0),
width: MediaQuery
.of(context)
.size
.width,
height: 85,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(child: Text(
"${snapshot.data.documents[index]
.data["dishname"]}", style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold),)),
//Icon: how to access if food is veg or not
],
),
// SizedBox(height:5),
Row(
children: <Widget>[
Expanded(child: Text(
"${snapshot.data.documents[index]
.data["homemaker"]}",
style: TextStyle(fontSize: 10),)),
Text("${snapshot.data.documents[index]
.data["rating"]}",
style: TextStyle(fontSize: 15)),
Icon(
Icons.star, color: Colors.yellow.shade800,
size: 20,)
],
),
SizedBox(height: 5),
//How to access order date
Text(
"Ordered ${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.day}/${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.month}/${DateTime
.parse(order['order_placed_at']
.toDate()
.toString())
.year}}",
style: TextStyle(fontSize: 15.0,
fontWeight: FontWeight.bold),
),
],
),
),
);
}),
);
} //
}),
);
}
This is how I am trying to display them...
int _selectedIndex = 3;
var uid;
Future<String> getUser() async {
final FirebaseUser user = await _auth.currentUser().then((val) {
setState(() {
uid = val.uid;
});
});
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
if (_selectedIndex == 0) {
Navigator.pushReplacementNamed(context, "/ExplorePage");
} else if (_selectedIndex == 1) {
Navigator.pushReplacementNamed(context, "/SearchPage");
} else if (_selectedIndex == 2) {
Navigator.pushReplacementNamed(context, "/FavoriteScreenPage",
arguments: uid);
}
}
TabController tabController;
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 20),
child: SizedBox(
height: 54,
child: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
backgroundColor: Color.fromRGBO(255, 255, 255, 0.8),
currentIndex: _selectedIndex,
selectedItemColor: Color(0xffFE506D),
onTap: _onItemTapped,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.explore,
color: Colors.black,
),
title: Text("Explore"),
),
BottomNavigationBarItem(
icon: Icon(Icons.search, color: Colors.black),
title: Text("Search"),
),
BottomNavigationBarItem(
icon: Icon(Icons.bookmark_border, color: Colors.black),
title: Text("Faavorites"),
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_identity, color: Color(0xffFE506D)),
title: Text("Shop"),
)
],
),
)),
drawer: DrawerWidget(uid: this.uid),
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.black),
elevation: 0,
),
backgroundColor: Color(0xffE5E5E5),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(25),
bottomLeft: Radius.circular(25)),
child: Container(
height: 230,
width: MediaQuery.of(context).size.width,
decoration: new BoxDecoration(
// border: new Border.all(width: 1.0, color: Colors.black),
shape: BoxShape.rectangle,
color: Colors.white,
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black,
offset: Offset(20.0, 30.0),
blurRadius: 40.0,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 155,
height: 155,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.cover,
image: new NetworkImage("$_image")))),
SizedBox(height: 10),
Text("$_name",
style: TextStyle(
fontSize: 25, fontWeight: FontWeight.bold))
],
),
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Container(
// margin: EdgeInsets.only(left: 15.0),
child: Container(
// margin: EdgeInsets.only(left: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
menuType = "profile";
});
},
child: Container(
margin: EdgeInsets.all(5.0),
child: Text(
getTranslated(context, "profile"),
style: TextStyle(
fontSize: menuType == "profile" ? 20.0 : 17.0,
color: menuType == "profile"
? Colors.black
: Colors.black45,
fontWeight: FontWeight.bold,
fontFamily: "Gilroy"),
)),
),
GestureDetector(
onTap: () {
setState(() {
menuType = "reviews";
});
},
child: Container(
margin: EdgeInsets.all(5.0),
child: Text(
getTranslated(context, "reviews"),
style: TextStyle(
fontSize: menuType == "reviews" ? 20.0 : 17.0,
color: menuType == "reviews"
? Colors.black
: Colors.black45,
fontWeight: FontWeight.bold,
fontFamily: "Gilroy"),
)),
),
GestureDetector(
onTap: () {
setState(() {
menuType = "recent";
});
},
child: Container(
margin: EdgeInsets.all(5.0),
child: Text(
getTranslated(context, "recent"),
style: TextStyle(
fontSize: menuType == "recent" ? 20.0 : 17.0,
color: menuType == "recent"
? Colors.black
: Colors.black45,
fontWeight: FontWeight.bold,
fontFamily: "Gilroy"),
)),
)
],
),
),
),
),
menuType== "profile"? this.ProfileItems() : this.ReviewItems() : this.RecentItems(),
],
),
),
);
}
}
this how I have declared menu type
final FirebaseAuth _auth = FirebaseAuth.instance;
Firestore firestore = Firestore.instance;
var _name, _uid, _phone, _language, _location, _image, menuType = "profile";
Language language;
I am not able to display the 3 tabs. The moment I remove recent widget it starts displaying.
Error displayed:
The following assertion was thrown building UserProfilePage(dirty, dependencies: [MediaQuery, _LocalizationsScope-[GlobalKey#47da7]], state: _UserProfilePageState#87b63):
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 285 pos 10: 'data != null'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
UserProfilePage file:///C:/Flutter/Naniz_eats/lib/main.dart:166:59
When the exception was thrown, this was the stack:
#2 new Text (package:flutter/src/widgets/text.dart:285:10)
#3 _UserProfilePageState.build (package:econoomaccess/UserProfilePage.dart:708:34)
#4 StatefulElement.build (package:flutter/src/widgets/framework.dart:4334:27)
#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4223:15)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5)
...
It seems the text is not present in your AppLocalization so you should do null check like this
String getTranslated(BuildContext context, String key) {
return AppLocalizations.of(context).translate(key) ?? "**text not found";
}
Related
How can i get rid of this strange white background? I want to use weather widget in my app and i want it to be above MyGridView with buttons. I tried to do it with expanded but im always getting white background and my widget. I would like to use my weather widget as normal widget (like others) and be able to apply padding in home_screen.dart etc.
home_screen.dart
Widget build(BuildContext context) {
Color _iconColor = Colors.white.withOpacity(0.1);
double Size = MediaQuery.of(context).size.width;
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Color(0xff362a19),
Color(0xff101011),
Color(0xff301119)
])),
child: Scaffold(
appBar: CustomAppBar(),
backgroundColor: Colors.transparent,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//IDEALNE https://github.com/Matt-rempel/flutter-weather-app/tree/master/assets/icons
Padding(
padding: EdgeInsets.only(top: 10, left: 25),
child: Text(
'${greeting()}',
style: TextStyle(
fontFamily: 'Helvetica Bold',
fontSize: 32,
color: Colors.white,
),
),
),
Padding(
padding: EdgeInsets.only(top: 10, left: 25),
child: Text(
'Zarządzaj swoimi urządzeniami',
style: TextStyle(
fontFamily: 'Helvetica Bold',
fontSize: 16,
color: Colors.grey,
fontWeight: FontWeight.w600),
),
),
Padding(
padding: EdgeInsets.only(top: 20, left: 25),
),
Expanded(
child: CurrentWeatherPage(locations, context), //<--------------------------- HERE
),
Expanded(
child: MyGridView(),
),
],
//
),
bottomNavigationBar: Container(
padding: const EdgeInsets.only(bottom: 18.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0),
),
child: BottomAppBar(
elevation: 0,
color: Colors.transparent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: Icon(
Icons.home,
color: _iconColor,
size: 28,
),
onPressed: null),
IconButton(
icon: Icon(
Icons.tv,
color: _iconColor,
size: 28,
),
onPressed: () {
setState(() {
_iconColor = Color(0xffc5073f);
});
}),
//
IconButton(
icon: Icon(
Icons.notifications,
color: _iconColor,
size: 28,
),
onPressed: null),
IconButton(
icon: Icon(
Icons.settings,
color: _iconColor,
size: 28,
),
onPressed: null),
],
),
),
),
//
) //
),
);
}
current_weather.dart
import 'package:firebaseauthproject/models/location.dart';
import 'package:firebaseauthproject/models/weather.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'extensions.dart';
class CurrentWeatherPage extends StatefulWidget {
final List<Location> locations;
final BuildContext context;
const CurrentWeatherPage(this.locations, this.context);
#override
_CurrentWeatherPageState createState() =>
_CurrentWeatherPageState(this.locations, this.context);
}
class _CurrentWeatherPageState extends State<CurrentWeatherPage> {
final List<Location> locations;
final Location location;
final BuildContext context;
_CurrentWeatherPageState(List<Location> locations, BuildContext context)
: this.locations = locations,
this.context = context,
this.location = locations[0];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
currentWeatherViews(this.locations, this.location, this.context)
],
),
);
}
}
Widget currentWeatherViews(
List<Location> locations, Location location, BuildContext context) {
Weather _weather;
return FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
_weather = snapshot.data;
if (_weather == null) {
return Text("Error getting weather");
} else {
return Column(children: [
weatherBox(_weather),
]);
}
} else {
return Center(child: CircularProgressIndicator());
}
},
future: getCurrentWeather(location),
);
}
Widget weatherBox(Weather _weather) {
return Stack(children: [
Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration: BoxDecoration(
color: Colors.indigoAccent,
borderRadius: BorderRadius.all(Radius.circular(20))),
),
ClipPath(
clipper: Clipper(),
child: Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration: BoxDecoration(
color: Colors.indigoAccent[400],
borderRadius: BorderRadius.all(Radius.circular(20))))),
Container(
padding: const EdgeInsets.all(15.0),
margin: const EdgeInsets.all(15.0),
height: 160.0,
decoration:
BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(20))),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
getWeatherIcon(_weather.icon),
Container(
margin: const EdgeInsets.all(5.0),
child: Text(
"${_weather.description.capitalizeFirstOfEach}",
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 16,
color: Colors.white),
)),
Container(
margin: const EdgeInsets.all(5.0),
child: Text(
"H:${_weather.high.toInt()}° L:${_weather.low.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 13,
color: Colors.white),
)),
])),
Column(children: <Widget>[
Container(
child: Text(
"${_weather.temp.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 60,
color: Colors.white),
)),
Container(
margin: const EdgeInsets.all(0),
child: Text(
"Feels like ${_weather.feelsLike.toInt()}°",
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 13,
color: Colors.white),
)),
])
],
),
)
]);
}
Image getWeatherIcon(String _icon) {
String path = 'assets/weather/';
String imageExtension = ".png";
return Image.asset(
path + _icon + imageExtension,
width: 70,
height: 70,
);
}
class Clipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = Path();
path.moveTo(0, size.height - 20);
path.quadraticBezierTo((size.width / 6) * 1, (size.height / 2) + 15,
(size.width / 3) * 1, size.height - 30);
path.quadraticBezierTo((size.width / 2) * 1, (size.height + 0),
(size.width / 3) * 2, (size.height / 4) * 3);
path.quadraticBezierTo((size.width / 6) * 5, (size.height / 2) - 20,
size.width, size.height - 60);
path.lineTo(size.width, size.height - 60);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.close();
return path;
}
#override
bool shouldReclip(Clipper oldClipper) => false;
}
Future getCurrentWeather(Location location) async {
Weather weather;
String city = location.city;
String apiKey = "0e97f1773e9ed9e93d3f99a91d14344f";
var url =
"https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric";
final response = await http.get(url);
if (response.statusCode == 200) {
weather = Weather.fromJson(jsonDecode(response.body));
}
return weather;
}
If you put two Expanded widgets in a Column, it will try to take equal amount space. If you want to get rid of that white space change your code from this...
Expanded(
child: CurrentWeatherPage(locations, context),
),
Expanded(
child: MyGridView(),
),
to this....
Flexible(
fit: FlexFit.tight,
child: CurrentWeatherPage(locations, context),
),
Expanded(
child: MyGridView(),
),
or if you want the two widgets share equal space in column change your code from this..
body: Column(
children: <Widget>[
currentWeatherViews(this.locations, this.location, this.context)
],
),
To this..
body: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
currentWeatherViews(this.locations, this.location, this.context)
],
),
First of all, i can't solve this title solutions which are already exist in stackoverflow, so i decided to open this topic.
it gives: Bad state: field does not exist within the DocumentSnapshotPlatform
, this error
how can i solve this? What is the problem, i can't find it, doc(dataPost.reference.parent.parent.id) may be problem but i am not sure.
note: There are users, and if user create any new post, then firestore create 'Posts' section in user uid's. I want to get all posts for homepage...
my codes and screenshot here:
class HomePageBodyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) => StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collectionGroup('Posts').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshotPost) {
if (snapshotPost.hasError) {
return Center(child: CircularProgressIndicator());
}
if (snapshotPost.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (!snapshotPost.hasData) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: snapshotPost.data.docs.length,
itemBuilder: (context, index) {
final dataPost = snapshotPost.data.docs[index];
if (!snapshotPost.hasData) {
return Center(child: CircularProgressIndicator());
}
return FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance
.collection('Users')
.doc(dataPost.reference.parent.parent.id)
.get(),
builder:
(context, AsyncSnapshot<DocumentSnapshot> snapshotUser) {
final dataUser = snapshotUser.data;
if (snapshotUser.hasError) {
return Center(child: CircularProgressIndicator());
}
if (snapshotUser.connectionState == ConnectionState.done) {
return homePageCard(
context,
dataPost: dataPost,
dataUser: dataUser,
);
}
return Center(child: CircularProgressIndicator());
},
);
});
});
}
homePageCard which has information about user and post:
Widget homePageCard(BuildContext context,
{dynamic dataUser, dynamic dataPost}) {
return Card(
child: Container(
width: 85,
height: 190,
decoration: BoxDecoration(color: Colors.teal[100]),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 11.0, left: 8),
child: CircleAvatar(
radius: 12,
backgroundImage:
NetworkImage(dataUser['profilePhotoUrl'])),
),
Padding(
padding: const EdgeInsets.only(top: 11.0, left: 3),
child: Text(dataUser['username']),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.only(right: 8.0, top: 11.0),
child: Text(
"dataPost['postDate'].toString()",
style:
const TextStyle(color: Colors.black54, fontSize: 13),
),
)),
const Padding(
padding: EdgeInsets.all(8.0),
child: Divider(
thickness: 0.3,
color: Colors.grey,
indent: 0,
height: 1,
),
),
],
),
],
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Divider(
thickness: 0.3,
color: Colors.black,
indent: 0,
height: 1,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
dataPost["postTitle"],
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 18.0, right: 18.0),
child: Text(
'\$' + dataPost['gamePrice'.toString()],
style: const TextStyle(
fontSize: 24,
color: Colors.black54,
fontWeight: FontWeight.w800),
),
),
),
Row(
children: <Widget>[
const Padding(
padding: EdgeInsets.only(left: 3.0, bottom: 5.0),
child: Icon(
Icons.my_location,
color: Colors.black54,
size: 18,
),
),
Padding(
padding: const EdgeInsets.only(left: 2.0, bottom: 3.0),
child: Text("dataPost['postCategory']",
style: const TextStyle(
fontSize: 12,
color: Colors.black54,
)))
],
),
const Padding(padding: EdgeInsets.only(top: 5.0)),
],
),
),
);
}
Everytime when I try to use loggegInUser property it returns null please help me to solve this issue
getCurrent() methods works properly and prints user email and password but I can not acces this variables in Build Widget.
class _ProfilePageState extends State<ProfilePage> {
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
String uid;
var url;
var userProfilePhotoUrl;
int currentPageIndex = 2;
CircularBottomNavigationController _navigationController =
new CircularBottomNavigationController(2);
List<TabItem> tabItems = List.of([
new TabItem(Icons.home, "Home", Colors.blue,
labelStyle: TextStyle(fontWeight: FontWeight.normal)),
new TabItem(Icons.add, "Let's Party", Colors.orange,
labelStyle: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)),
new TabItem(Icons.person, "Reports", Colors.red),
]);
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
uid = user.uid;
print(loggedInUser.email);
print(uid);
}
} catch (e) {
print(e);
}
}
void changePage(int index) {
setState(() {
currentPageIndex = index;
});
}
Future<FirebaseImage> getFirebaseProfilPhoto() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
uid = user.uid;
print(loggedInUser.email);
print(uid);
return FirebaseImage(
'gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png');
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
setState(() {
getCurrentUser();
});
return Scaffold(
appBar: AppBar(
title: Text('furkanakguun'),
),
body: Builder(
builder: (context) => Container(
color: Colors.black,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.black,
backgroundImage: FirebaseImage(
'gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png'),
// FirebaseImage(
// 'gs://homeparty-68792.appspot.com/user_profile_images/$uid.png'),
//backgroundImage: Image.network(userProfilePhotoUrl),
radius: 100,
),
Padding(
padding: EdgeInsets.only(top: 60.0),
child: IconButton(
icon: Icon(
FontAwesomeIcons.camera,
size: 30.0,
),
focusColor: Colors.white,
color: Colors.deepPurple,
onPressed: () {
print('asd');
Navigator.pushNamed(context, 'image_uploader');
},
),
),
],
),
Divider(),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.person),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text('Furkan Akgün',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
),
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.location_on),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text('Ankara',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
),
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Row(
children: <Widget>[
Card(
color: Colors.grey[900],
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(Icons.rate_review),
),
Card(
color: Colors.grey[900],
margin:
EdgeInsets.symmetric(horizontal: 10.0, vertical: 7.0),
child: Container(
child: SmoothStarRating(
spacing: 2.0,
allowHalfRating: true,
starCount: 5,
rating: 4.5,
size: 20,
color: Colors.yellow,
borderColor: Colors.white,
isReadOnly: true,
)),
),
],
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 40.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
color: Colors.deepPurple[900],
onPressed: () {
//uploadPic(context);
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Edit',
style: TextStyle(color: Colors.white, fontSize: 16.0),
),
),
],
)
],
),
),
),
bottomNavigationBar: CircularBottomNavigation(
tabItems,
barBackgroundColor: Colors.deepPurple[900],
controller: _navigationController,
selectedCallback: (int selectedPos) {
if (selectedPos == 0) {
Navigator.pushNamed(context, 'dashboard_screen');
}
if (selectedPos == 2) {
Navigator.pushNamed(context, 'user_profile');
}
},
),
);
}
}
enter image description here
ERROR TYPE
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The getter 'uid' was called on null.
Receiver: null
Tried calling: uid)
My guess is that the error comes from this code in your build method:
FirebaseImage('gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png')
This is because the UI may be built before the user sign-in is completed.
To prevent this from happening you need to handle the fact that the user may not be signed in, in your build code too, for example by skipping the rendering of their profile image:
backgroundImage: loggedInUser != null ?
FirebaseImage('gs://homeparty-68792.appspot.com/user_profile_images/${loggedInUser.uid}.png') :
Text("Loading...")
I am trying to get images from firebase by using StreamBuilder widget. Tried all what I know but no result. As classes connected with each other tight everything gets tangled. here images are retrieved from manually created list as indicated above but I want to replace them with images from firebase. Please review code and help
class MyApp extends StatefulWidget {
static const String id = 'Myapp_screen';
#override
_MyAppState createState() => new _MyAppState();
}
var cardAspectRatio = 12.0 / 16.0;
var widgetAspectRatio = cardAspectRatio * 1.2;
class _MyAppState extends State<MyApp> {
var currentPage = images.length - 1.0;
#override
Widget build(BuildContext context) {
PageController controller = PageController(initialPage: images.length - 1);
controller.addListener(() {
setState(() {
currentPage = controller.page;
});
});
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xEFEFEF),
Color(0xFFFF),
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
tileMode: TileMode.clamp)),
child: Scaffold(
backgroundColor: Colors.transparent,
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 12.0, right: 12.0, top: 30.0, bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
CustomIcons.menu,
color: Colors.blue,
size: 30.0,
),
onPressed: () {},
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.blue,
size: 30.0,
),
onPressed: () {},
)
],
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Trending",
style: TextStyle(
color: Colors.blue,
fontSize: 46.0,
fontFamily: "Calibre-Semibold",
letterSpacing: 1.0,
)),
IconButton(
icon: Icon(
CustomIcons.option,
size: 12.0,
color: Colors.white,
),
onPressed: () {},
)
],
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Color(0xFFff6e6e),
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 22.0, vertical: 6.0),
child: Text("Animated",
style: TextStyle(color: Colors.white)),
),
),
),
SizedBox(
width: 15.0,
),
Text("25+ Stories",
style: TextStyle(color: Colors.blueAccent))
],
),
),
Stack(
children: <Widget>[
CardScrollWidget(currentPage),
Positioned.fill(
child: PageView.builder(
itemCount: images.length,
controller: controller,
reverse: true,
itemBuilder: (context, index) {
return Container();
},
),
)
],
),
],
),
),
bottomNavigationBar: NavigationBottomBar(),
),
),
);
}
}
And this is for card scroll
class CardScrollWidget extends StatelessWidget {
var currentPage;
var padding = 20.0;
var verticalInset = 20.0;
CardScrollWidget(this.currentPage);
#override
Widget build(BuildContext context) {
return new AspectRatio(
aspectRatio: widgetAspectRatio,
child: LayoutBuilder(builder: (context, contraints) {
var width = contraints.maxWidth;
var height = contraints.maxHeight;
var safeWidth = width - 2 * padding;
var safeHeight = height - 2 * padding;
var heightOfPrimaryCard = safeHeight;
var widthOfPrimaryCard = heightOfPrimaryCard * cardAspectRatio;
var primaryCardLeft = safeWidth - widthOfPrimaryCard;
var horizontalInset = primaryCardLeft / 2;
List<Widget> cardList = new List();
for (var i = 0; i < images.length; i++) {
var delta = i - currentPage;
bool isOnRight = delta > 0;
var start = padding +
max(
primaryCardLeft -
horizontalInset * -delta * (isOnRight ? 15 : 1),
0.0);
var cardItem = Positioned.directional(
top: padding + verticalInset * max(-delta, 0.0),
bottom: padding + verticalInset * max(-delta, 0.0),
start: start,
textDirection: TextDirection.rtl,
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Container(
decoration: BoxDecoration(color: Colors.white, boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(3.0, 6.0),
blurRadius: 10.0)
]),
child: AspectRatio(
aspectRatio: cardAspectRatio,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(images[i], fit: BoxFit.cover),
Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.0, vertical: 8.0),
child: Text(title[i],
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
fontFamily: "SF-Pro-Text-Regular")),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(
left: 12.0, bottom: 12.0),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 22.0, vertical: 6.0),
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)),
child: Text("Read Later",
style: TextStyle(color: Colors.white)),
),
)
],
),
)
],
),
),
),
),
);
cardList.add(cardItem);
}
return Stack(
children: cardList,
);
}),
);
}
}
Manually created list of images
List<String> images = [
"assets/image_04.jpg",
"assets/image_03.jpg",
"assets/image_02.jpg",
"assets/image_01.png",
];
Please add below StreamBuilder Widget code...<br>
StreamBuilder(
stream: Firestore.instance
.collection('details')
.document(documentId)
.collection(collectionId)
.orderBy('timestamp', descending: true)
.limit(20)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Colors.green)));
} else {
listMessage = snapshot.data.documents;
return Padding(
padding: const EdgeInsets.only(
top: 5.0, right: 5.0, left: 5.0),
child: ListView.builder(
itemCount: snapshot.data.documents.length,
reverse: true,
itemBuilder: (context, index) =>
buildItem(index, snapshot.data.documents[index]),
),
);
}
},
));
then make one method that return widget which contains layout of your ListView items.
Widget buildItem(int index, DocumentSnapshot document) {
return Container(
child: CachedNetworkImage(
placeholder: (context, url) => Container(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Colors.black),
),
width: 200.0,
height: 200.0,
padding: EdgeInsets.all(70.0),
decoration: BoxDecoration(
color: Colors.lightGreen[200],
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
imageUrl: document['imgUrl'],
width: 200.0,
height: 200.0,
fit: BoxFit.cover,
),
}
I want to upload the image to firebase storage in want to store the download URL in the firestore. I have the code that I have bellowed! but the problem is whenever I try to upload an image the image upload successfully but the URL did not save in the firestore. It's returns me Null.
How can I store the URL to firestore?
class NewFund extends StatefulWidget {
NewFund();
#override
_NewFundState createState() => _NewFundState();
}
class _NewFundState extends State<NewFund> {
final GlobalKey<FormState> _fundFormKey = GlobalKey<FormState>();
String userID, postName, postDetails, postImgUrl;
String filepath = '${DateTime.now()}.png';
File _imageFile;
StorageUploadTask _uploadTask;
final FirebaseStorage _storage =
FirebaseStorage(storageBucket: 'gs://i-donate-402dd.appspot.com');
getUserName(userId) {
this.userID = userID;
}
getPostName(postName) {
this.postName = postName;
}
getTaskDetails(postDetails) {
this.postDetails = postDetails;
}
getImageUrl(postImgUrl) {
this.postImgUrl = postImgUrl;
}
int _myPostType = 0;
String postVal;
void _handleTaskType(int value) {
setState(() {
_myPostType = value;
switch (_myPostType) {
case 1:
postVal = 'food';
break;
case 2:
postVal = 'health';
break;
case 3:
postVal = 'money';
break;
case 4:
postVal = 'clothes';
break;
case 5:
postVal = 'education';
break;
}
});
}
Widget radioButton(bool isSelected) => Container(
width: 16.0,
height: 16.0,
padding: EdgeInsets.all(2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(width: 2.0, color: Colors.black)),
child: isSelected
? Container(
width: double.infinity,
height: double.infinity,
decoration:
BoxDecoration(shape: BoxShape.circle, color: Colors.black),
)
: Container(),
);
Widget horizontalLine() => Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Container(
width: ScreenUtil.getInstance().setWidth(120),
height: 1.0,
color: Colors.black26.withOpacity(.2),
),
);
createFund() {
var authP = Provider.of<AuthP>(context);
var uid = authP.uid;
DocumentReference ds =
Firestore.instance.collection('posts').document(postName);
Map<String, dynamic> posts = {
"userID": uid,
"postName": postName,
"postDetails": postDetails,
"postCat": postVal,
"postImgUrl": postImgUrl,
};
setState(() {
_saveImage();
});
ds.setData(posts).whenComplete(() {
print("posts updated");
});
}
Future<String> _saveImage() async {
_uploadTask = _storage.ref().child(filepath).putFile(_imageFile);
var downURL = await (await _uploadTask.onComplete).ref.getDownloadURL();
postImgUrl = downURL.toString();
print('LINK URL : $postImgUrl');
return postImgUrl;
}
Future<void> _pickImage(ImageSource source) async {
File selected = await ImagePicker.pickImage(source: source);
setState(() {
_imageFile = selected;
});
}
#override
Widget build(BuildContext context) {
ScreenUtil.instance = ScreenUtil.getInstance()..init(context);
ScreenUtil.instance =
ScreenUtil(width: 750, height: 1334, allowFontScaling: true);
return Form(
key: _fundFormKey,
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomPadding: true,
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20.0),
child: Image.asset("assets/imagemain.jpg"),
),
Expanded(
child: Container(),
),
Image.asset("assets/image_02.png")
],
),
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 28.0, right: 28.0, top: 60.0),
child: Column(
children: <Widget>[
SizedBox(
height: ScreenUtil.getInstance().setHeight(20),
),
Container(
width: double.infinity,
height: ScreenUtil.getInstance().setHeight(850),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0),
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, -10.0),
blurRadius: 10.0),
]),
child: Padding(
padding:
EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Raise Fund",
style: TextStyle(
fontSize:
ScreenUtil.getInstance().setSp(45),
fontFamily: "Poppins-Bold",
letterSpacing: .6)),
SizedBox(
height: ScreenUtil.getInstance().setHeight(30),
),
Text("Title",
style: TextStyle(
fontFamily: "Poppins-Medium",
fontSize:
ScreenUtil.getInstance().setSp(26))),
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(),
onChanged: (String name) {
getPostName(name);
},
),
SizedBox(
height: ScreenUtil.getInstance().setHeight(30),
),
Text("Fund Details",
style: TextStyle(
fontFamily: "Poppins-Medium",
fontSize:
ScreenUtil.getInstance().setSp(26))),
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(),
onChanged: (String postDetails) {
getTaskDetails(postDetails);
},
),
SizedBox(
height: ScreenUtil.getInstance().setHeight(30),
),
Text("Select Fund Type",
style: TextStyle(
fontFamily: "Poppins-Bold",
fontSize:
ScreenUtil.getInstance().setSp(26))),
SizedBox(
height: ScreenUtil.getInstance().setHeight(30),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 1,
groupValue: _myPostType,
onChanged: _handleTaskType,
activeColor: Color(0xff4158ba),
),
Text(
'Food',
style: TextStyle(fontSize: 16.0),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 2,
groupValue: _myPostType,
onChanged: _handleTaskType,
activeColor: Color(0xfffb537f),
),
Text(
'Health',
style: TextStyle(
fontSize: 16.0,
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 3,
groupValue: _myPostType,
onChanged: _handleTaskType,
activeColor: Color(0xff4caf50),
),
Text(
'Money',
style: TextStyle(fontSize: 16.0),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 4,
groupValue: _myPostType,
onChanged: _handleTaskType,
activeColor: Color(0xff9962d0),
),
Text(
'Clothes',
style: TextStyle(fontSize: 16.0),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 5,
groupValue: _myPostType,
onChanged: _handleTaskType,
activeColor: Color(0xff0dc8f5),
),
Text(
'Education',
style: TextStyle(fontSize: 16.0),
),
],
),
],
),
],
),
),
),
SizedBox(
height: ScreenUtil.getInstance().setHeight(20),
),
RaisedButton(
onPressed: () {
_pickImage(ImageSource.gallery);
},
child: Text('Upload Document'),
),
SizedBox(
height: ScreenUtil.getInstance().setHeight(20),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
child: Container(
width: ScreenUtil.getInstance().setWidth(330),
height: ScreenUtil.getInstance().setHeight(100),
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF17ead9),
Color(0xFF6078ea)
]),
borderRadius: BorderRadius.circular(6.0),
boxShadow: [
BoxShadow(
color: Color(0xFF6078ea).withOpacity(.3),
offset: Offset(0.0, 8.0),
blurRadius: 8.0)
]),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
createFund();
},
child: Center(
child: Text("Raise",
style: TextStyle(
color: Colors.white,
fontFamily: "Poppins-Bold",
fontSize: 18,
letterSpacing: 1.0)),
),
),
),
),
)
],
),
],
),
),
)
],
),
),
);
}
}
here is how you can implement it
final StorageReference storageReference =
FirebaseStorage.instance.ref().child('images/$name');
StorageUploadTask uploadTask = storageReference.putData(asset);
final StreamSubscription<StorageTaskEvent> streamSubscription =
uploadTask.events.listen((event) {
// You can use this to notify yourself or your user in any kind of way.
// For example: you could use the uploadTask.events stream in a StreamBuilder instead
// to show your user what the current status is. In that case, you would not need to cancel any
// subscription as StreamBuilder handles this automatically.
});
await uploadTask.onComplete;
streamSubscription.cancel();
//get your ref url
String docUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
//docUrl is your url as a string
Firestore.instance
.collection('collectiion')
.document()
.updateData({"url": docUrl});