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

I have a collection of user_profile in my app console. I want to retrieve a doc (a particular user profile with its user id [click to check][1]).
I know that FirebaseAuth.instance.currentUser; would give me the current login user ID but that is not what I want. I want to show the details of the clicked user, not the logged_in user, can't seem to find any answer here that was helpful. Please help guys
This is the method that gets the collection
Future<DocumentSnapshot> getUserData() {
var firebaseUser = FirebaseAuth.instance.currentUser;
_firestoreInstance
.collection('user_profile')
.doc(firebaseUser.uid)
.get()
.then((value) {
print(value.data());
return value.data();
});
}
and here is my future builder
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getUserData(),
// ignore: missing_return
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Error fetching user profile');
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> userData = snapshot.data.data();
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: () {
// Navigator.pushNamed(context, Homepage.id);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 30,
),
),
),
GestureDetector(
onTap: () {},
child: Stack(
children: [
CircleAvatar(
radius: 70,
backgroundColor: Colors.transparent,
child: ClipOval(
child: Image.asset('assets/avatar_profile.jpg'),
),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white60,
radius: 25,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.edit, color: Colors.blueGrey),
),
),
)
],
),
),
SizedBox(
height: 10,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${userData['nickname']}",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 3,
width: 20,
color: Colors.white,
),
Text(
// '7',
"{$userData['age]}",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Card(
child: Column(
children: [
ListTile(
leading: Icon(
Icons.person,
size: 40,
),
title: Text("About me"),
isThreeLine: false,
dense: true,
subtitle: Text("${userData['aboutMe']}"),
trailing: Icon(Icons.arrow_right),
)
],
),
),
),
Expanded(
child: Container(
width: 400,
child: ListView(
children: [
ProfileListTile(
leading: Icons.phone_in_talk,
title: 'Phone Number',
subtitle: "${userData['mobile']}",
),
ProfileListTile(
leading: Icons.add_location,
title: 'Current Location',
subtitle: "${userData['location']}",
),
ProfileListTile(
leading: FontAwesomeIcons.heartbeat,
title: 'Relationship Status',
subtitle: "${userData['maritalStatus']}",
),
ProfileListTile(
leading: Icons.people,
title: 'Gender',
subtitle: 'Male',
),
ProfileListTile(
leading: Icons.looks,
title: 'Interested In',
subtitle: "${userData['InterestedIn']}",
),
],
),
),
),
],
),
),
));
}
},
);
}
}

Your code is currently not returning anything from getUserData yet. The only return you have is inside the then function, and doesn't escape to the higher level.
The simplest way to fix it is by using await:
Future<DocumentSnapshot> getUserData() async {
var firebaseUser = FirebaseAuth.instance.currentUser;
var doc = await _firestoreInstance
.collection('user_profile')
.doc(firebaseUser.uid)
.get()
return doc.data();
}

It sounds like you would like your app's users to see other people's profile.
To do that, you would first have to accept the uid of the user to display the profile. Then you can pass the uid to the future like the following example:
class ProfilePage extends StatelessWidget {
const ProfilePage({
Key key,
#required this.uid, // Here you are receiving the uid of the currently viewd user's uid
}) : super(key: key);
final String uid;
#override
Widget build(BuildContext context) {
return FutureBuilder<Map<String, dynamic>>(builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error fetching user profile'));
}
final userProfile = snapshot.data;
return Column(
children: [
// Here you would paste the contents of your user profile widget
],
);
});
}
Future<Map<String, dynamic>> getUserData() async {
final snap =
await _firestoreInstance.collection('user_profile').doc(uid).get();
return snap.data();
}
}

I was able to solve this easily by just passing from usersCard to UserProfile (my bad, lolx), since I already have this data on list users screen, there was no need to fetching them again with FutureBuilder
class UsersCard extends StatelessWidget {
final Users usersDetails;
const UsersCard({Key key, #required this.usersDetails}) : super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) =>
UserProfile(userDetails: usersDetails))); //im passing the data here
},
child: Stack(
children: [
Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.network(
'https://placeimg.com/170/170/any',
fit: BoxFit.contain,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
),
Positioned(
left: 20,
bottom: 20,
child: IntrinsicHeight(
child: Row(
children: [
Text(
'${usersDetails.nickname}',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 2,
width: 20,
color: Colors.white,
),
Text(
'${usersDetails.age}',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900),
),
],
),
),
),
],
),
);
}
}
Here is my UsersProfile Screen
class UserProfile extends StatelessWidget {
final Users userDetails;
UserProfile({#required this.userDetails});
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: () {
// Navigator.pushNamed(context, Homepage.id);
},
icon: Icon(
Icons.arrow_back,
color: Colors.white,
size: 30,
),
),
),
GestureDetector(
onTap: () {},
child: Stack(
children: [
CircleAvatar(
radius: 70,
backgroundColor: Colors.transparent,
child: ClipOval(
child: Image.asset('assets/avatar_profile.jpg'),
),
),
Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
backgroundColor: Colors.white60,
radius: 25,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.edit, color: Colors.blueGrey),
),
),
)
],
),
),
SizedBox(
height: 10,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${userDetails.nickname}",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w900),
),
VerticalDivider(
thickness: 3,
width: 20,
color: Colors.white,
),
Text(
// '7',
"{$userDetails.age}",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Card(
child: Column(
children: [
ListTile(
leading: Icon(
Icons.person,
size: 40,
),
title: Text("About me"),
isThreeLine: false,
dense: true,
subtitle: Text("${userDetails.aboutMe}"),
trailing: Icon(Icons.arrow_right),
)
],
),
),
),
Expanded(
child: Container(
width: 400,
child: ListView(
children: [
ProfileListTile(
leading: Icons.phone_in_talk,
title: 'Phone Number',
subtitle: "${userDetails.mobile}",
),
ProfileListTile(
leading: Icons.add_location,
title: 'Current Location',
subtitle: "${userDetails.location}",
),
ProfileListTile(
leading: FontAwesomeIcons.heartbeat,
title: 'Relationship Status',
subtitle: "${userDetails.maritalStatus}",
),
ProfileListTile(
leading: Icons.people,
title: 'Gender',
subtitle: 'Male',
),
ProfileListTile(
leading: Icons.looks,
title: 'Interested In',
subtitle: "${userDetails.interestedIn}",
),
],
),
),
),
],
),
),
),
);
}
}

Related

I want to display PDFs and images in Firebase Storage

I would like to use FirebaeStorage to display PDFs and images.
↓The code below is the code to display the file list
(I was able to get the data from Firebase and display the List.)
class Gakubu extends StatefulWidget {
const Gakubu({Key? key}) : super(key: key);
#override
State<Gakubu> createState() => _GakubuState();
}
class _GakubuState extends State<Gakubu> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('学部'),
),
body: Container(
child: ListView(
children: [
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('工学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => kougaku(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('情報理工学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => zyouhourikou(),
)
), ),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('教育学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => kyouiku(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('獣医学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => zyuui(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('理学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => rigaku(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('生命科学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => seimei(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('生物地球学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => seibutu(),
)
),
),
),
Card(
child: ListTile(
leading: Icon(Icons.folder),
trailing: Icon(Icons.chevron_right),
title: Text('経営学部'),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => keiei(),
)
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//ポップアップメニュー実装
showModalBottomSheet(
//モーダルの背景の色、透過
backgroundColor: Colors.transparent,
//ドラッグ可能にする(高さもハーフサイズからフルサイズになる様子)
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 150),
decoration: BoxDecoration(
//モーダル自体の色
color: Colors.white,
//角丸にする
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'過去問をアップロード',
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
Padding(
padding: const EdgeInsets.all(8.0), //マージン
child: SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton.icon(
icon: Icon(Icons.photo_library),
label: Text(
'アルバムから選択',
textAlign: TextAlign.left,
),
onPressed: () {},
),
),
),
Padding(
padding: const EdgeInsets.all(8.0), //マージン
child: SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton.icon(
icon: Icon(Icons.camera),
label: Text(
'写真を撮る',
textAlign: TextAlign.left,
),
onPressed: () {},
),
),
),
Padding(
padding: const EdgeInsets.all(8.0), //マージン
child: SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton.icon(
icon: Icon(Icons.folder),
label: Text(
'複数以上のファイル',
textAlign: TextAlign.left,
),
onPressed: () => launch(
'https://docs.google.com/forms/d/e/1FAIpQLSda45WF5uVd9mRFs_4nPCiM6bxFqpUKZSApYFWUVlAVtDlg_g/viewform?usp=sf_link')),
),
),
Padding(
padding: const EdgeInsets.all(8.0), //マージン
child: SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton.icon(
icon: Icon(Icons.link),
label: Text(
'ドライブなどのURL',
textAlign: TextAlign.left,
),
onPressed: () => launch(
'https://docs.google.com/forms/d/e/1FAIpQLSdEIS3eOynTihQ3AEk0zrp7mSpmcfqpEGxTOUIDp6Mzi19jqA/viewform?usp=sf_link')),
),
),
Text(
'アップロードあざます!',
style: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
],
),
);
});
},
child: const Icon(Icons.upload_rounded),
)
,
);
}
}
This code is for displaying images and PDFs. (This code can only display PDFs.)
class ImagePage extends StatelessWidget {
final FirebaseFile file;
const ImagePage({
Key? key,
required this.file,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final isImage = ['.jpeg', '.jpg', '.png'].any(file.name.contains);
final isPdf = ['.pdf'].any(file.name.contains);
return Scaffold(
appBar: AppBar(
title: Text(file.name),
centerTitle: true,
),
body: SfPdfViewer.network(
file.url
),
);
}
}
final isImage = ['.jpeg', '.jpg', '.png'].any(file.name.contains);
final isPdf = ['.pdf'].any(file.name.contains);
Here I would like to have the process change depending on the file extension.
for example
sfpdfview for PDF
imageview for image
Any ideas?

Closure call with mismatched arguments: function '[]' in flutter

** I am getting this error**
Closure call with mismatched arguments: function '[]'
Receiver: Closure: (dynamic) => dynamic from Function 'get':.
Tried calling: []("url")
Found: [](dynamic) => dynamic
my code where I am receiving the data from firestore is this..
import 'package:flutter/material.dart';
import 'package:riyazat_quiz/services/database.dart';
import 'package:riyazat_quiz/views/create_quiz.dart';
import 'package:riyazat_quiz/widgets/widgets.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
Stream quizStream;
DatabaseService databaseService = DatabaseService(); // this is to call the getQuizData() async{
return await FirebaseFirestore.instance.collection("Quiz").snapshots();
}
Widget quizList(){
return Container(
child: StreamBuilder(
stream:quizStream ,
builder: (context,snapshort){
return snapshort.data == null ? CircularProgressIndicator(): ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount : snapshort.data.documents.length ,
itemBuilder : (context,index){ return QuizTile(url:snapshort.data.documents[index].get['url'],
title:snapshort.data.documents[index].get['title'] ,
desc: snapshort.data.documents[index].get['desc'],);}
);
}
),
);
}
#override
void initState() {
databaseService.getQuizData().then((val){
setState(() {
quizStream =val;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: appBar(context),
),
backgroundColor: Colors.transparent,
elevation: 0.0,
brightness: Brightness.light,
),
body:
Column(
children: [
quizList(),
FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => CreateQuiz()));
},
),
],
),
);
}
}
class QuizTile extends StatelessWidget {
final String url,title,desc;
QuizTile({#required this.url,#required this.title,#required this.desc});
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: [
Image.network(url),
Container(
child: Column(
children: [
Text(title),
Text(desc),
],
),
)
],
),
);
}
}
can someone tell me where I am going wrong
ps: this is a quiz app where I am getting the data from the firestore,
using streams.
data saved on the firestore has three fields, "url", "title" "desc".
I want to retrieve them in the below widget and want to display them in a stack, but this error got me stuck in-between.
You need to do the following:
itemCount : snapshort.data.docs.length ,
itemBuilder : (context,index){
return QuizTile(url:snapshort.data.docs[index].data()['url'],
title:snapshort.data.docs[index].data()['title'] ,
desc: snapshort.data.docs[index].data()['desc'],
);
}
);
Since you are reference a collection, then you need to use docs which will retrieve a list of documents inside that collection:
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart#L18
Then to access each field in the document, you need to call data()
The answer by #Peter Haddad is correct. Just to highlight the difference with an example from my own code:
The previous version of code which created the same error:
snapshot.data.docs[index].data["chatRoomID"]
Updated version of code which solved the error:
snapshot.data.docs[index].data()["chatRoomID"]
Updated Version:
snapshot.data[i]['Email'],
Future getRequests() async {
QuerySnapshot snapshot = await FirebaseFirestore.instance.collection("Buyer Requests").get();
return snapshot.docs;
}
body: FutureBuilder(
initialData: [],
future: getRequests(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
indexLength = snapshot.data.length;
if (snapshot.hasData)
return SizedBox(
child: PageView.builder(
itemCount: indexLength,
controller: PageController(viewportFraction: 1.0),
onPageChanged: (int index) => setState(() => _index = index),
itemBuilder: (_, i) {
return SingleChildScrollView(
child: Card(
margin: EdgeInsets.all(10),
child: Wrap(
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage(
'assets/images/shafiqueimg.jpeg'),
),
title: Text(
snapshot.data[i]['Email'],
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Colors.black.withOpacity(0.7),
),
),
subtitle: Text(
snapshot.data[i]['Time'],
style: TextStyle(
color: Colors.black.withOpacity(0.6)),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(5)),
color: Colors.grey[200],
),
padding: EdgeInsets.all(10),
child: Text(
snapshot.data[i]['Description'],
style: TextStyle(
color: Colors.black.withOpacity(0.6)),
),
),
SizedBox(
height: 8,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5)),
border: Border.all(
color: Colors.grey[300])),
child: ListTile(
leading: Icon(Icons.category_outlined),
title: Text(
'Category : ${snapshot.data[i]['Category']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
),
),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5)),
border: Border.all(
color: Colors.grey[300])),
child: ListTile(
leading: Icon(Icons.location_pin),
title: Text(
snapshot.data[i]['Location'],
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
),
),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5)),
border: Border.all(
color: Colors.grey[300])),
child: ListTile(
leading: Icon(
Icons.attach_money,
color: kGreenColor,
),
title: Text(
'Rs.${snapshot.data[i]['Budget']}',
style: TextStyle(
fontSize: 14,
color: kGreenColor,
),
),
),
),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5)),
border: Border.all(
color: Colors.grey[300])),
child: ListTile(
leading: Icon(Icons.timer),
title: Text(
'Duration : ${snapshot.data[i]['Duration']}',
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
),
),
SizedBox(
height: 35,
),
RaisedButton(
padding: EdgeInsets.symmetric(vertical: 10),
child: Text('Send Offer'),
textColor: Colors.white,
color: Colors.green,
onPressed: () {
// Respond to button press
},
),
SizedBox(
height: 15,
),
Center(
child: Text(
"${i + 1}/$indexLength",
style: TextStyle(fontSize: 13),
),
),
],
),
),
],
),
),
);
},
),
);
else
return Center(
child: Text("Null"),
);
},
),
Given that you are referencing a collection, you must use docs to acquire a list of the documents included in that collection:
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud firestore/cloud firestore/lib/src/query snapshot.dart#L18
then you must call data() in order to access each field in the document.

FLUTTER Profile picture disappears when user leaves page

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

flutter :sharedpreference retrieving null value [duplicate]

This question already has answers here:
What is a NoSuchMethod error and how do I fix it?
(2 answers)
Closed 2 years ago.
The method 'getStringList' was called on null.
Receiver: null
Tried calling: getStringList("userCart")
The relevant error-causing widget was:
Consumer .the details are stored in firebase,the error occurs when displaying the no of items the user have added to the cart.
the CartItemCounter dart file is that thrown error when calling consumer.initially useCart is given as garbage value when registering in firebase.
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
class StoreHome extends StatefulWidget {
#override
_StoreHomeState createState() => _StoreHomeState();
}
class _StoreHomeState extends State<StoreHome> {
SharedPreferences sharedPreferences;
#override
void initState() {
super.initState();
SharedPreferences.getInstance().then((prefs){
setState(() {
sharedPreferences=prefs;
});
});
}
#override
Widget build(BuildContext context) {
final _width=MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("E_shop",style: TextStyle(color:Colors.red,),
),
centerTitle: true,
actions: [
Stack(
children: [
IconButton(icon:Icon(Icons.add_shopping_cart,color: Colors.grey,),
onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>StoreHome()));
},
),
Positioned(child: Stack(
children: [
Icon(Icons.brightness_1,size: 20.0,
color: Colors.green,),
Positioned(
top: 3.0,
bottom: 4.0,
left:4.0,
child: Consumer<CartItemCounter>(
builder: (context, counter,_){
return Text(
counter.count.toString(),
style:TextStyle(color:Colors.white,fontSize:12.0,fontWeight:FontWeight.w500),
);
},),
),
],
),
),
],
),
],
),
drawer: MyDrawer(),
body: CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: SearchBoxDelegate(),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("items").limit(15).orderBy("publishedDate",descending: true).snapshots(),
builder: (context,dataSnapshot){
return !dataSnapshot.hasData
?SliverToBoxAdapter(child: Center(child: circularProgress(),),)
:SliverStaggeredGrid.countBuilder(
crossAxisCount: 1,
itemCount: 5,
staggeredTileBuilder: (c)=>StaggeredTile.fit(1),
itemBuilder: (context,index){
ItemModel model=ItemModel.fromJson(dataSnapshot.data.docs[index].data());
return sourceInfo(model,context);
},
);
},
),
],
),
),
);
}
circularProgress(){
return Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 12.0),
child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.lightGreenAccent),),
);
}
Widget sourceInfo(ItemModel model, BuildContext context , {Color background, removeCartFunction}) {
return InkWell(
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>ProductPage(itemModel:model)));
},
splashColor: Colors.pink,
child: Padding(
padding: EdgeInsets.all(6.0),
child: Container(
height: 300.0,
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Image.network(model.thumbnailUrl ,width:140.0,height: 140.0,),
SizedBox(width: 4.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.0,),
Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(child: Text(
model?.title ?? '',style: TextStyle(color: Colors.black,fontSize: 14.0),
),
)
],
),
),
SizedBox(height: 5.0,),
Container(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(child: Text(
model?.shortInfo ?? '',style: TextStyle(color: Colors.black54,fontSize: 12.0),
),
)
],
),
),
SizedBox(height: 20.0,),
Row(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.pink,
),
alignment: Alignment.topLeft,
width: 40.0,
height: 43.0,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"50%",style: TextStyle(
fontSize: 15.0,color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
"OFF",style: TextStyle(
fontSize: 12.0,color: Colors.white,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
SizedBox(width: 10.0,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 0.0),
child: Row(
children: [
Text(
"Original Price :%",
style: TextStyle(
fontSize: 14.0,
color: Colors.grey
),
),
Text(
(model?.price??'').toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
decoration: TextDecoration.lineThrough,
),
)
],
),
),
Padding(
padding: EdgeInsets.only(top: 5.0),
child: Row(
children: [
Text(
"New Price :%",
style: TextStyle(
fontSize: 16.0,
color: Colors.red,
),
),
Text(
"%",
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
),
),
Text(
(model.price+model.price).toString(),
style: TextStyle(
fontSize: 15.0,
color: Colors.grey
),
),
],
),
),
],
),
],
),
Flexible(child: Container(
),
),
//to implement cart add/remove remove
Align(
alignment: Alignment.centerRight,
child: removeCartFunction==null
?IconButton(
icon: Icon(Icons.add_shopping_cart,color: Colors.pinkAccent,),
onPressed: (){
checkItemInCart(model.shortInfo,context);
},)
:IconButton(
icon: Icon(Icons.delete),
onPressed: null)
)
],
))
],
),
),
),
);
}
void checkItemInCart(String shortInfoAsId, BuildContext context) {
sharedPreferences.getStringList(EcommerceApp.userCartList).contains(shortInfoAsId)
?Fluttertoast.showToast(msg: "item already in cart")
:addItemToCart(shortInfoAsId,context);
}
addItemToCart(String shortInfoAsId, BuildContext context) {
List tempCartList=sharedPreferences.getStringList(EcommerceApp.userCartList);
tempCartList.add(shortInfoAsId);
FirebaseFirestore.instance.collection("users").doc(sharedPreferences.getString(EcommerceApp.userUID))
.update({
EcommerceApp.userCartList: tempCartList,
}).then((value){
Fluttertoast.showToast(msg: "Item added to cart successfully");
sharedPreferences.setStringList(EcommerceApp.userCartList, tempCartList);
Provider.of<CartItemCounter>(context,listen: false).displayResult();
});
}
}```
the CartItemCounter dart file is that thrown error when calling consumer<cartitemcounter>.initially useCart is given as garbage value when registering in firebase.
```class CartItemCounter extends ChangeNotifier{
static SharedPreferences sharedPreferences;
int _counter=sharedPreferences.getStringList("userCart").length-1;
int get count=>_counter;
Future<void> displayResult() async{
int _counter=sharedPreferences.getStringList("userCart").length-1;
await Future.delayed(const Duration(milliseconds: 100),(){
notifyListeners();
});
}
}```
The method 'getStringList' was called on null.
Receiver: null
Tried calling: getStringList("userCart")
The relevant error-causing widget was:
Consumer<CartItemCounter> .the details are stored in firebase,the error occurs when displaying the no of items the user have added to the cart.
The error:
getStringList("...") was called on null
implies that the method was called on a null object which means that you are trying to call sharedPrefs.getStringList()
but, sharedPrefs is null at the moment as it has not been loaded yet. Hence, you encounter the problem. A simple hack to solve this problem:
#override
Widget build(BuildContext context) {
final _width=MediaQuery.of(context).size.width;
return SafeArea(
child:
sharedPrefs == null? // If sharedPrefs is not retreived yet
Scaffold(body: Center(child: Text("Hold on :)"))): // Show this widget
Scaffold( // Else do your normal job
appBar: AppBar(
title: Text("E_shop",style: TextStyle(color:Colors.red,),
),
......... and so on..

View FIrestore Data as a Table in Flutter

I am currently working on a project in which I need to retrieve some firestore and view them as a table
I have tried datatable but cells are overflowing
There are seven fixed columns & n no of rows.
Can someone help me with this?
My whole code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
import 'package:intl/intl.dart';
class view extends StatefulWidget {
#override
_view createState() => _view();
}
class _view extends State<view> {
Future getPosts() async{
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore.collection('data').getDocuments();
return qn.documents;
}
DateTime Date = DateTime.now();
var i = 0;
Future<void> _Date(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: Date,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101));
if (picked != null && picked != Date)
setState(() {
Date = picked;
});
}
String dropdownValue = '';
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Color(0xFF11249F),
title: new Text("VIEW DATA",
style: new TextStyle(color: Colors.white),),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
Row(
children: <Widget>[
SizedBox(width: 10,),
Container(
child: Text ('Select Factory',style: TextStyle(
fontSize: 14.5,
fontFamily: "Quando",
fontWeight: FontWeight.bold,
color: Colors.deepPurple
),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
height: 50,
width: 200,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: Color(0xFFE5E5E5),
),
),
child:Row(
children: <Widget>[
SizedBox(width: 20),
Expanded(
child: DropdownButton(value: dropdownValue,
isExpanded: true,
icon: Icon(Icons.arrow_downward),
style: TextStyle(fontSize: 13,
fontFamily: "Quando",
fontWeight: FontWeight.w500,
color: Colors.deepPurple),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>['','Vapi', 'Masat']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
]
),
),
]
),
SizedBox(
height: 30,
),
Column(
children: <Widget>[
Row(
children: <Widget>[
SizedBox(width: 10,),
Container(
child: Text('Date',style: TextStyle(
fontSize: 14.5,
fontFamily: "Quando",
fontWeight: FontWeight.bold,
color: Colors.deepPurple
),
),
),
SizedBox(width: 80,),
Text("${Date.toLocal()}".split(' ')[0],style: TextStyle(
fontSize: 14.5,
fontFamily: "Quando",
fontWeight: FontWeight.bold,
color: Colors.deepPurple
),),
SizedBox(width: 20.0,),
RaisedButton(
onPressed: () => _Date(context),
textColor: Colors.white,
padding: const EdgeInsets.all(0.0),
child:Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFF0D47A1),
Color(0xFF1976D2),
Color(0xFF42A5F5),
]
)
),
padding: const EdgeInsets.all(10.0),
child:
const Text('Select Date', style: TextStyle(fontSize: 14)),
) ,
),
],
),
SizedBox(height: 30,),
Container(
child: FutureBuilder(
future: getPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text('Loading...',style: TextStyle(
fontSize: 14.5,
fontFamily: "Quando",
fontWeight: FontWeight.bold,
color: Colors.deepPurple
),),
);
}
else {
String formattedDate = DateFormat('yyyy-MM-dd').format(Date);
return new SizedBox(
height: 1000,
child :GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (Orientation == Orientation.landscape) ? 7 : 7),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
if (snapshot.data[index].data['Date'] ==
formattedDate &&
snapshot.data[index].data['Plant'] ==
dropdownValue) {
i++;
return DataTable(
columns: [
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
DataColumn(
label: Text(
"Work Centre",style: TextStyle(
fontStyle:FontStyle.italic
),
)
),
],
rows: [
DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
DataCell(Text('Sarah')),
DataCell(Text('Sarah')),
DataCell(Text('Sarah')),
DataCell(Text('Sarah')),
],
)
],
);
}
else {
return Container();
}
}
));
}
} )
)
]
)
]
)
)
));
}
}
Problem : Screenshot
PS: Data written in row is temporary I will change it later to get data from firestore, I need 7 cols & n no of rows just like excel sheet
There are two ways to overcome this problem:
make your app responsive: display a specific number of columns in mobile mode, and another in tablet mode.
you can overcome the overflow problem by make you table horizontally & vertically scrollable like this:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: SingleChildScrollView(
child: SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(label: Text('RollNo')),
DataColumn(label: Text('Name')),
DataColumn(label: Text('Class')),
DataColumn(label: Text('Hello')),
DataColumn(label: Text('World')),
],
rows: [
DataRow(cells: [
DataCell(Text('1')),
DataCell(Text('Arya')),
DataCell(Text('6')),
DataCell(Text('Arya')),
DataCell(Text('6')),
]),
DataRow(cells: [
DataCell(Text('12')),
DataCell(Text('John')),
DataCell(Text('9')),
DataCell(Text('Arya')),
DataCell(Text('6')),
]),
DataRow(cells: [
DataCell(Text('42')),
DataCell(Text('Tony')),
DataCell(Text('8')),
DataCell(Text('Arya')),
DataCell(Text('6')),
]),
],
),
),
),
),
);
}

Resources