" the method where isn't defined for the type documentreference"? - firebase

why i'm i getting this error " the method where isn't defined for the type documentreference"?
is there any other way to filter documents?
buildPostHeader() {
return FutureBuilder(
future:Firestore.instance.collection('users').document(id).where('designer',isEqualTo:true).get(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return circularProgress();
}
User user = User.fromDocument(snapshot.data);
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0))
),
margin: EdgeInsets.only(top:10.0,left: 10.0,right: 10.0, bottom: 10.0 ),
child: Column(
children: <Widget> [
ListTile(
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(user.photoUrl),
backgroundColor: Colors.grey,
),
title: Text(user.displayName,style: TextStyle(color: Colors.white),),
subtitle: GestureDetector(
onTap: () => showProfile(context, profileId: user.id),
child: Text(
user.username,
style: TextStyle(
color: kText,
fontWeight: FontWeight.bold,
),
),
),

Problem with above code -
You are specifing an document Id so you will get a single document and where can only be applied to List or Iterable
Firestore.instance.collection('users').where('designer',isEqualTo:true).getDocuments(),
Try to use this code it will return a Future<QuerySnapShot> and snapshot.data.documents is a List<DocumentSnapShot> which passed the where condition if you want to filter it again by id or something else you can do it by using where to snapshot.data.documents
final data = snapshot.data.documents.where(condition);

Related

Flutter - How to make a call on Flutter Firestore, return value if it contains?

I'm building a system. Purpose product search. But I'm having a problem with this search. I want this search system like this: If what the person is looking for is in any value, it should be returned as a result. For example, if the person is looking for shoes as a product, when I type sho, I want it to come to the listView.
Or let me give you another example: Finding the glass when typing gla for glass. How can I make this search system?
Firestore:
I tried a code like this:
Container(
height: 200,
child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance.collection("bolatAktar").where("urunAdi", isEqualTo: _arananUrun).snapshots(), // !!!!!!!!!!!!!!<<<<<<<<<<<<<<<<<<<<<
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
return InkWell(
child: ListTile(
leading: Icon(Icons.label),
title: Text(snapshot.data!.docs[index].data()["urunAdi"], style: TextStyle(fontSize: 20),),
),
onTap: () {
showModalBottomSheet(
isScrollControlled:true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
context: context,
builder: (context) {
return FractionallySizedBox(
heightFactor: 0.93,
child: Container(
padding: EdgeInsets.all(25),
height: MediaQuery.of(context).size.height * 0.5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Product name:", style: TextStyle(fontSize: 20)),
SizedBox(height: 10),
TextFormField(
style: TextStyle(fontSize: 19),
decoration: InputDecoration(
border: OutlineInputBorder(),
),
initialValue: snapshot.data!.docs[index].data()["urunAdi"],
),
]
)
),
);
}
);
},
);
},
);
}
},
),
),
Result:
Thank you in advance for your help and valuable information.
Google Firestore: Query on substring of a property value (text search)
Is there a way to search sub string at Firestore?
Firestore Comparison Operators - contains, does not contain, starts with
I have reviewed the above topics, but they did not contribute because they are not up to date.

FirebaseFirestore.instance.collectionGroup('some'),subCollection is displaying same duplicated data for Nth user even though other user didnt upload

I'm using StreamBuilder to fetch data from cloud Firestore subcollection. It's working, but it's duplicating data for every user in the database, like user(mario) posted his pic and other user(bowser) posted his pic but in emulator it's showing mario's pic for both mario and bowser as if they both uploaded the same pic.
I have attached screenshots to clear my question as I couldn't ask clearly. Is this happening because of the collectionGroup statement or is it a logic error? And, how do I solve this problem?
Here is the pic of database:
Below is my code.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
bottomNavigationBar: BottomNavigation(),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
title: Text(
"Platform",
style: TextStyle(
color: Colors.white,
fontSize: 32.6,
fontWeight: FontWeight.bold,
fontFamily: "Yaldevi",
)
)
),
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collectionGroup('posts').snapshots(),
builder:(context, AsyncSnapshot<QuerySnapshot> snapshot){
final List<DocumentSnapshot> document = snapshot.data!.docs;
return ListView(
children: document.map((doc) => Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collectionGroup('usersData').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot){
final List<DocumentSnapshot> data = snapshot.data!.docs;
return Column(
children: data.map((docs) => Column(
children: [
ListTile(
leading: docs['profileImage'] == null ?
CircleAvatar(
radius: 16.6,
backgroundColor: Colors.white24,
) :
CircleAvatar(
radius: 16.6,
backgroundImage: NetworkImage(
docs['profileImage'],
),
),
title: Text(
docs['displayName'],
style: TextStyle(
color: Colors.white,
)
),
subtitle: doc['title'] != null ?
Text(
doc['title'],
style: TextStyle(
color: Colors.white,
)
) :
Text(
"PUTA"
)
),
Container(
height: 400,
width: 400,
decoration: doc['photoURL'] != null ?
BoxDecoration(
image: DecorationImage(
image: NetworkImage(
doc['photoURL'],
),
fit: BoxFit.contain,
)
) :
BoxDecoration(
color: Colors.white24,
)
)
]
)).toList(),
);
}
),
)
],
)).toList(),
);
}
)
);

How to show Timestamp String in DateFormat in flutter firebase [duplicate]

This question already has answers here:
Converting timestamp
(22 answers)
Closed 1 year ago.
I am fetching the TimeStamp store in the database directly using document['eventDate'] I can't display the TimeStamp so I am converting it to string document['eventDate'].toString(), it is giving me the output you can see below
I tried converting it to DateTime format DateFormat('dd-MM-yyyy') but it is was showing error saying
Class 'DateTime' has no instance method 'DateFormat'.
Is there any way through which I can show the date.
Data is getting stored in below format
Code
Widget getHomePageBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('events').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
default:
return new ListView(
padding: EdgeInsets.only(bottom: 80),
children: snapshot.data.docs.map((DocumentSnapshot document) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10),
child: Card(
child: ListTile(
leading: new Image.network(
document['eventImageUrl'],
fit: BoxFit.cover,
width: 120.0,
),
title: new Text(
'Date:' + (document['eventDate'].toDate()).DateFormat('kk:mm:a').format(),
style: new TextStyle(
color: Color(0xFF49DEE8),
fontSize: 14.0,
fontWeight: FontWeight.normal),
),
),
),
);
}).toList(),
);
}
},
);
}
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
model.hwPublishedDate
.toDate()
.hour
.toString() +
":" +
model.hwPublishedDate
.toDate()
.minute
.toString() +
" " +
model.hwPublishedDate
.toDate()
.timeZoneName
.toString() +
", " +
model.hwDate,
style: GoogleFonts.abel(
color: Colors.green[500],
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
),
)
],
),
),
ListTile(
leading: Icon(
Icons.calendar_today_sharp,
color: Colors.green[900],
),
title: DateTimeField(
validator: (value) =>
value == null ? 'Provide Upload Date' : null,
showCursor: true,
cursorColor: Colors.green,
textCapitalization: TextCapitalization.words,
style: TextStyle(color: Colors.green[900]),
controller: _hwdateTextEditingController,
decoration: InputDecoration(
hintText: "Date",
hintStyle: TextStyle(
color: Colors.green[900],
),
border: InputBorder.none),
format: DateFormat("dd-MM-yyyy"),
onShowPicker: (context, currentValue) {
return showDatePicker(
context: context,
firstDate: DateTime(1947),
initialDate: currentValue ?? DateTime.now(),
lastDate: DateTime(2100));
},
onChanged: (selectedCateg) {
setState(() {
queryString = selectedCateg.toString();
classSec = selectedClass + selectedSec;
});
startSearching(classSec);
},
),
),
You first go with .toDate().toString() and then format it using Date Format, and the Listile is how I store Date if you want you can use it that way too

how to fetch data from firestore array of a document with flutter?

this is my users collection in cloud fire store:
users collection
this is the function that gets users from users collection in firestore
Stream<QuerySnapshot> fetchUsersInSearch() {
return Firestore.instance.collection('users').snapshots();
}
i use this method
final emailResults = snapshot.data.documents
.where((u) => u['email'].contains(query));
in the following streamBuilder to fetch users by their email.
i have this streamBuilder to populate the data on screen
return StreamBuilder<QuerySnapshot>(
stream: DatabaseService().fetchUsersInSearch(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
final emailResults = snapshot.data.documents
.where((u) => u['email'].contains(query));
if (!snapshot.hasData) {
return Container(
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
'',
style: TextStyle(
fontSize: 16, color: Theme.of(context).primaryColor),
),
),
);
}
if (emailResults.length > 0) {
return Container(
color: Theme.of(context).primaryColor,
child: ListView(
children: emailResults
.map<Widget>((u) => GestureDetector(
child: Padding(
padding: const EdgeInsets.all(0.1),
child: Container(
padding: EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
border: Border(
bottom: BorderSide(
width: 0.3, color: Colors.grey[50]))),
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).primaryColor,
backgroundImage:
NetworkImage(u['userAvatarUrl']),
radius: 20,
),
title: Container(
padding: EdgeInsets.only(left: 10),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(u['email'],
style: TextStyle(
fontSize: 16,
color: Theme.of(context)
.accentColor),
overflow: TextOverflow.ellipsis),
SizedBox(
height: 5,
),
],
),
),
),
),
),
onTap: () {
showUserProfile(u['id']);
},
))
.toList(),
),
);
} else {
return Container(
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
'No results found',
style: TextStyle(
fontSize: 16,
color: Theme.of(context).accentColor,
),
),
),
);
}
});
this is working perfectly and fetching users inside a listView by their email...
p.s: the (query) is a string i type in a seach bar.
how can i make a query to fetch users by their otherUsernames...the second field in the screenshot of the users collection ?!
i tried this:
final otherUsernamesResults = snapshot.data.documents
.where((u) => u['otherUsernames'].contains(query));
but its returning this error:
The method 'contains' was called on null.
Receiver: null
Tried calling: contains("#username1")
what am i doing wrong here ?!!
any help would be much appreciated..
Try this:-
Stream<QuerySnapshot> getUsers() {
final usersCollection = FirebaseFirestore.instance.collection('users');
return usersCollection.where('otherUsernames', arrayContainsAny: ['username1', 'username2']);
}
For firestore version 0.16.0

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.

Resources