Related
I guys, I have a News Flutter app that fetch articles from WordPress API,I have this code in my app but I don't know how to show up articles from search bar.
As you can see in the body of the Home page I have a busy body homepage because there are tabs widgets to show up.
I share screens to understand my case.
Is there another way to show up results maybe using a search delegate?
HomePage
searchbar page
Empty searchbar when I search keyword, no results
Home screen with tabs to load
class SearchBar extends StatefulWidget{
final List<Article> posts;
const SearchBar({Key? key, required this.posts,}) : super(key: key);
#override
_SearchBarState createState() => _SearchBarState();
}
class _SearchBarState extends State<SearchBar> {
final List<Article> _searchedPost = [];
late List<Article> _searchedArticles = [];
late final data;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
decoration: const InputDecoration(
hintText: "Cerca Articolo",
border: InputBorder.none,
),
onChanged: (val) {
setState(() {
_searchedArticles = widget.posts.where((element) => element.title!.contains(val)).toList();
});
},
),
),
body: _searchedArticles.isEmpty ?
Scaffold(
body: Padding(padding: const EdgeInsets.all(12),
child: Column(
children: [
Image.asset("assets/images/search-illustration.png", height: 230,),
const SizedBox(height: 20,),
const Text('Nessun articolo trovato!',
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 20,),
const Text('Inserisci meglio le lettere o parole chiave dell’articolo che stai cercando e riprova.',
style: TextStyle(
fontSize: 16.0,
color: Colors.black54,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 30,),
MaterialButton(
height: 50,
elevation: 0,
color: Colors.blue[900],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: const [
Text('Torna alla home', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600),),
],
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => HomePage(),
),
);
},
),
],
),
),
) : ListView.builder(
itemCount: _searchedArticles.length,
itemBuilder: (context, i) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Card(
margin: const EdgeInsets.all(10),
elevation: 5,
shadowColor: Colors.black26,
child: InkWell(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
//data["_embedded"]["wp:featuredmedia"][0]["link"],),
_searchedArticles[i].urlImage == null
? const Text("Nessuna immagine caricata")
: Image.network(data["_embedded"]["wp:featuredmedia"][0]["link"],
width: double.infinity,
height: 220,
fit: BoxFit.cover,
),
// Title article
Column(
children: [
Padding(
padding: const EdgeInsets.only(
left: 16, top: 16, bottom: 16),
child: Row(
children: [
Expanded(
child: Text(_searchedArticles[i].title as String,
maxLines: 3,
overflow: TextOverflow.clip,
softWrap: true,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
,
),
),
),
],
),
)
],
),
],
),
),
onTap: () {
if (_searchedPost[i] != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(
data: _searchedPost[i],
),
),
);
}
},
),
),
],
);
},
),
);
}
}```
Home page
class HomePage extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<HomePage> with SingleTickerProviderStateMixin {
TabController? _tabController;
final List<Tab> topTabs = <Tab>[
const Tab(child: Text("Notizie")),
const Tab(child: Text("Fiscalità ")),
const Tab(child: Text("Gestione")),
const Tab(child: Text("Business")),
const Tab(child: Text("Documentazione")),
];
#override
void initState() {
/// Start tabs articles
_tabController = TabController(length: topTabs.length, initialIndex: 0, vsync: this)..addListener(() {setState(() {});});
super.initState();
/// End tabs articles
}
/// tabs
Future<bool> _onWillPop() async {
if (_tabController?.index == 0) {
await SystemNavigator.pop();
}
Future.delayed(const Duration(microseconds: 200), () {
_tabController?.index = 0;
});
return _tabController?.index == 0;
}
final _scaffoldKey = GlobalKey<ScaffoldState>();
///
///
/// Search page
final List<Article> _posts = [];
#override
Widget build(BuildContext context) {
return Container(
child: WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
key: _scaffoldKey,
extendBody: true,
drawer: NavbarMenu(),
backgroundColor: const Color(0xFFFAFAFA),
appBar: AppBar(
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return GestureDetector(
child: Center(
child: IconButton(
icon: const Icon(
Icons.dehaze_outlined,
color: Colors.white,
),
onPressed: () {
Scaffold.of(context).openDrawer();
},
),
),
);
},
),
backgroundColor: Colors.blue[900],
centerTitle: true,
title: Image.asset('assets/images/bird.png', fit: BoxFit.contain, height: 32,),
/// Action search icon
actions: <Widget>[
/// First search icon
IconButton(
icon: const Icon(Icons.search, color: Colors.white,),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context)=> SearchBar(posts: _posts,)
));
},
),
],
/// Bottom tab bar
bottom: TabBar(
controller: _tabController,
indicatorColor: const Color(0xFFF9E14B),
tabs: topTabs,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(
width: 4.0,
color: Color(0xFFF9E14B),
),
insets: EdgeInsets.symmetric(horizontal: 10.0, vertical: 0),
),
labelColor: Colors.yellow,
unselectedLabelColor: Colors.white,
isScrollable: true,
labelStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
fontFamily: "Raleway"),
unselectedLabelStyle: const TextStyle(
fontWeight: FontWeight.w400,
fontSize: 14,
),
),
),
/// Body
body: TabBarView(
controller: _tabController,
children: const [
//SearchBar(posts: [],),
NewsPage(),
FiscalitaPage(),
GestionePage(),
BusinessPage(),
DocumentazionePage(),
],
),
///
),
),
);
}```
Flutter:How to convert Cards UI or View to Individual View Please find the HomeScreen Page code and try to convert to detailed individual view
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:gadjet_inventory/Form/ListTiles.dart';
import 'package:gadjet_inventory/main.dart';
import 'package:intl/intl.dart';
import 'package:gadjet_inventory/Form/Data.dart';
import 'UploadData.dart';
import 'package:pdf_flutter/pdf_flutter.dart';
// ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<Data> dataList = [];
List<bool> favList = [];
bool searchState = false;
FirebaseAuth auth = FirebaseAuth.instance;
#override
void initState() {
// TODO: implement initState
super.initState();
DatabaseReference referenceData = FirebaseDatabase.instance.reference().child("Data");
referenceData.once().then((DataSnapshot dataSnapShot) {
dataList.clear();
favList.clear();
var keys = dataSnapShot.value.keys;
var values = dataSnapShot.value;
for (var key in keys) {
Data data = new Data(
values [key]['imgUrl'],
values [key]['wcpdfUrl'],
values [key]['ugpdfUrl'],
values [key]['cattegorrytype'],
values [key]['companyname'],
values [key]['modelname'],
values [key]['seriesname'],
values [key]['year'],
key
//key is the uploadid
);
dataList.add(data);
auth.currentUser().then((value) {
DatabaseReference reference = FirebaseDatabase.instance.reference().child("Data").child(key).child("Fav")
.child(value.uid).child("state");
reference.once().then((DataSnapshot snapShot){
if(snapShot.value!=null){
if(snapShot.value=="true"){
favList.add(true);
}else{
favList.add(false);
}
}else{
favList.add(false);
}
});
});
}
Timer(Duration(seconds: 1),(){
setState(() {
//
});
});
});
}
int selectedRadioTile;
String get path => null;
String get title => null;
setSelectedRadioTile(int val) {
setState(() {
selectedRadioTile = val;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightGreen,
//Color(0xffffffff),
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.blue,
title: new Text("Device Details", style:
TextStyle(fontSize: 20), textAlign: TextAlign.center),
actions: <Widget>[
IconButton(icon: Icon(Icons.refresh, size: 36, color: Colors.white,),
onPressed: () {
//debugPrint("Add New Device Cattegorry");
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ListTiles();
}
)
); //
},
),
IconButton(icon: Icon(Icons.home, size: 36, color: Colors.white,),
onPressed: () {
//debugPrint("Add New Device Cattegorry");
Navigator.push(context, MaterialPageRoute(builder: (context) {
return MyHomePage();
}
)
); //
},
)
],),
body: dataList.length == 0
? Center(
child: Text("No Data Available", style: TextStyle(fontSize: 30),))
: ListView.builder(
itemCount: dataList.length,
itemBuilder: (_, index) {
return CardUI(dataList[index].imgUrl,dataList[index].wcpdfUrl, dataList[index].cattegorrytype,
dataList[index].companyname, dataList[index].modelname,dataList[index].seriesname,dataList[index].year,
dataList[index].uploadid,index);
}
),
);
}
Widget CardUI(String imgUrl, String wcpdfUrl,String cattegorrytype, String companyname, String modelname,
String seriesname, String year ,
String uploadId,int index) {
return Card(
elevation: 7,
margin: EdgeInsets.all(15),
//color: Color(0xffff2fc3),
color:Colors.blueGrey,
child: Container(
color: Colors.white,
margin: EdgeInsets.all(1.5),
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Image.network(
imgUrl != null
? imgUrl
: '',
width: 500,
height: 500,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text( "Cattegorry Type:- "
"$cattegorrytype",
style: TextStyle(color: Colors.black),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(
hintColor: Colors.blue,
),
child: Text( "Company Name:- "
"$companyname",
style: TextStyle(color: Colors.black),
),
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(
hintColor: Colors.blue,
),
child: Text( "Model Name:- "
"$modelname",
style: TextStyle(color: Colors.black),
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(
hintColor: Colors.blue,
),
child: Text( "Series Name:- "
"$seriesname",
style: TextStyle(color: Colors.black),
),
),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(
hintColor: Colors.blue,
),
child: Text( "Year Of MFG:- "
"$year",
style: TextStyle(color: Colors.black),
),
),
),
),
],
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: Colors.blue,
child: Text("Warranty Card",
style: TextStyle(fontSize: 18, color: Colors.white),),
),
RadioListTile(
value: 1,
groupValue: selectedRadioTile,
title: Text("PDF"),
//subtitle: Text("Upload PDF File"),
/* onChanged: (val) {
filePicker(context);
},*/
activeColor: Colors.red,
),
Padding(padding: EdgeInsets.only(top: 15)),
// _buildPDF1Field(context),
PDF.network(
wcpdfUrl != null
? wcpdfUrl
: '',
width: 600,
height: 1000, placeHolder: Image.asset("assets/images/pdf.png",
height: 600, width: 500),
),
SizedBox(height: 24),
],
),
),
);
}
I have uploaded few text items one imageUrl and one pdf document to firebase storage and able to retrieve them in HomeScreen View (card UI or View (cards list) and List Tile View( with one image and one text, when tapped on it should show each individual view).
Please guide me How to convert to Individual Retrieving page instead of group of vertical cards list.
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}",
),
],
),
),
),
],
),
),
),
);
}
}
** 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.
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'),
),
),
);
}
}