I am trying to get only the groups to which the user belongs, but with the current code I show all the existing groups.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("My groups"),
automaticallyImplyLeading: false,
),
body: StreamBuilder(
stream: userColeccion.doc('$userID').collection("grupos").snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
Text("groups users"),
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("grupos")
.snapshots(),
builder: (context, groupSnapshot) {
if (groupSnapshot.hasData) {
var groupList = (groupSnapshot.data
as QuerySnapshot<Map<String, dynamic>>)
.docs
.map((d) => Group.fromJson(d.data()))
.toList();
return ListView.builder(
itemCount: groupList.length,
itemBuilder: (context, index) {
var group = groupList[index];
return Card(
child: ListTile(
title: Text(group.namegroup),
),
);
},
);
}
return const Center(child: CircularProgressIndicator());
},
),
),
],
);
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}
when entering "users", you can enter the id of each one, within that id there is a collection called "groups" which stores the key of the different groups to which the user belongs, with this key I intend to search in the "groups" collection that is at the "users" level, but it stores the key of the groups that exist.
collection "usuarios"
collection "grupos"
In short, I would like to show on the screen only the groups to which the user belongs, the keys are stored by the user, thank you very much for any help or explanation.
To get the documents from grupos where namegroup is equal to Grupo 2, you can use a query:
stream: userColeccion.doc('$userID').collection("grupos")
.where("namegroup", "==", "Grupo 2")
.snapshots(),
'Uid', isEqualTo:FirebaseAuth.instance.currentUser!.uid... in the fields also add the uid of the current so it should checking
Related
I'm using/learning Firebase for my database works. My snapshot's coming like _jsonQuerySnapshot or _jsonDocumentSnapshot. But it had to be QuerySnapshot or DocumentSnapshot. Because of this I have to encode and decode my snapshot for use my datas.
If I'm not using encode decode json I'm getting null or object errors all the time.
Here is my class extends from state
class _MyHomePageState extends State<MyHomePage> {
final _firestore = FirebaseFirestore.instance;
#override
Widget build(BuildContext context) {
CollectionReference moviesRef=_firestore.collection('movies');
DocumentReference babaRef = _firestore.collection('movies').doc('Baba');
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: Text('FireStore Crud'),
),
body: Center(
child: Container(
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: moviesRef.snapshots(),
builder: (BuildContext context,AsyncSnapshot asyncSnapshot){
List<DocumentSnapshot>listOfDocumentSnapshot=asyncSnapshot.data.docs;
return Flexible(
child: ListView.builder(
itemCount: listOfDocumentSnapshot.length,
itemBuilder: (context,index){
Text('${listOfDocumentSnapshot[index].data()['name']}' ,style: TextStyle(fontSize: 24),);
},
),
);
},
),
],
),
),
),
);
}
}
and this is my error .
First of all, check your data is null or not and then use [] on it. Probably, listOfDocumentSnapshot[index].data() is null. If it is null, render another UI such as loading screen. Namely, your loading screen must be showed until reach the data.
for example:
builder: (BuildContext context,AsyncSnapshot asyncSnapshot){
List<DocumentSnapshot>? listOfDocumentSnapshot = asyncSnapshot.data.docs;
if(!listOfDocumentSnapshot.hasData || listOfDocumentSnapshot == null){
return LoadingScreen(); //etc.
}
return Flexible(
child: ListView.builder(
itemCount: listOfDocumentSnapshot.length,
itemBuilder: (context,index){
Text('${listOfDocumentSnapshot[index].data()['name']}' ,style: TextStyle(fontSize: 24),);
},
),
);
},
Futures (asynchronous programmes) need some time to get data and you have to make your UI wait until you get your data. e.g. database connections, read/write somethings to/from somewhere etc.
For more detail you can read this article.
I am looking to retrieve data stored in Firebase Realtime database and display it in a new page in a lisview, how can I achieve that. So far I can retrieve and print it out in a console terminal.
My code is below:
class BarcodesResultPreviewWidget extends StatelessWidget {
FirebaseDatabase.instance.reference().child('ScannedResults');
body: Column(
children: <Widget>[
previewView,
//printing scanned results
Expanded(
child: ListView.builder(
itemBuilder: (context, position) {
return BarcodeItemWidget(preview.barcodeItems[position]);
},
itemCount: preview.barcodeItems.length,
),
),
FlatButton(
color: Colors.grey,
child: Text('Save',),
onPressed: () {
databaseRef.push().set({
'ScannedItem': preview.barcodeItems
.map((barCodeItem) => barCodeItem.toJson())
.toString(),
});
},
),
To fetch the data into a new page and build listview, try something like this:
return Scaffold(
body: FutureBuilder(
future: databaseRef.once(),
// future: FirebaseDatabase.instance
// .reference()
// .child("ScannedResults")
// .once(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return new Text('Loading....');
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
List scannedItemsValues = [];
snapshot.data.value.forEach(
(_, values) => scannedItemsValues.add(values["ScannedItem"]));
print(scannedItemsValues);
return ListView.builder(
itemCount: scannedItemsValues.length,
itemBuilder: (BuildContext context, int index) {
// build your listView here
print(scannedItemsValues[index]);
return Text(scannedItemsValues[index]);
},
);
},
),
);
I am using two quires to fetch data from the firestore.
Query 1.
_firestore
.collection('chats')
.doc(getCurrentUser().uid)
.collection('chatUsers')
.orderBy('timestamp');
with all the querysnapshot document from query 1. I am fetching last message and document id, and displaying the last message in listTile. With document id i am passing the id to fetch other data from other collection like name photo etc.
Query 2.
Future<DocumentSnapshot> fetchUserData(String uid) async => await _firestore
.collection('users')
.doc(uid).get();
So for this I need to use nested stream builder. First stream builder to fetch all data. Second stream builder to fetch user requested data from all data. what will be the best approach?
This is how i am using query 1 in my widgets for the query 2 I have to implement it inside the ListView.builder which will be the nested stream. please guide me with the best approach to this.
SafeArea(
child: Scaffold(
body: StreamBuilder<QuerySnapshot>(
stream: _fetchUserChatRoom.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return _tiles(snapshot.data.docs);
} else if (snapshot.hasError) {
return Icon(Icons.error_outline);
} else {
return CircularProgressIndicator();
}
}),
),
);
}
Widget _tiles(List<QueryDocumentSnapshot> docs) {
return ListView.builder(
itemCount: docs.length,
itemBuilder: (BuildContext context, int index) {
var data = ChatModel.fromMap(docs[index].data());
return GestureDetector(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (_) => ChatScreen(uid: docs[index].id))),
child: ListTile(
leading: CircleAvatar(),
title: Text(data.message),
subtitle: Text(data.timestamp.toString()),
trailing: Text('time'),
),
);
});
You can either use async and await in your ListView.builder, however, I imaging this could slowdown you app and cause a lot of firestore calls.
Widget _tiles(List<QueryDocumentSnapshot> docs) {
return ListView.builder(
itemCount: docs.length,
itemBuilder: (BuildContext context, int index) async {
var data = ChatModel.fromMap(docs[index].data());
var userData = await fetchUserData(data[index].uid);
return GestureDetector(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (_) => ChatScreen(uid: docs[index].id))),
child: ListTile(
leading: CircleAvatar(),
title: Text(data.message),
subtitle: Text(data.timestamp.toString()),
trailing: Text('time'),
),
);
});
Other options (which I use) is to use a Provider class with all the contacts. You can fill the Provider when the app initializes with all the users in your firestore. After that you can use each user data anywhere in your app.
This is my firebase each group of documents added by different user I want to get the documents based in the userId filed I sored that filed in id variable and that is my code the condition is not working, it gets me all documents in glucose collection
stream: FirebaseFirestore.instance
.collection('glucose')
.where('userId', isEqualTo: id)
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
for (int index = 0;
index < snapshot.data.docs.length;
index++) {
DocumentSnapshot documentSnapshot = snapshot.data.docs[index];
chartData.add(ChartData.fromMap(documentSnapshot.data()));
}
Try the below query, let me know if it works :)
Also, in this case you will probably going to get Map so you can use .map((e) => null).toList() to get them in list and render them using ListView or Column or what ever suits you :)
StreamBuilder(
stream:
FirebaseFirestore.instance.collection('glucose').snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return ListView(
children: snapshot.data.docs.map(
(singleDoc) {
if (snapshot.data.docs.contains(singleDoc['userID']))
return Card(
child: ListTile(
title: Text(
singleDoc['someFieldHere'],
),
),
);
},
).toList(),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
This below code will retrieve all the information from the collection but i want to retrieve only the current user information. How can i do that?
class Booking extends State<BookingDetails> {
final databaseReference = Firestore.instance;
var firebaseUser = FirebaseAuth.instance.currentUser();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Appbar"),
),
body: Center(
child: Container(
padding: const EdgeInsets.all(10.0),
child: StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('User1').snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new Text('Loading...');
default:
return new ListView(
children: snapshot.data.documents
.map((DocumentSnapshot document) {
return new CustomCard(
title: document['name'],
description: document['phno'],
);
}).toList(),
);
}
},
)),
),
);
}
}
I want to store multiple documents for a user and i want to retrieve and show only his documents from Firestore how to do that?
If you want to retrieve information of the current user, then in that case you have to retrieve one document. Example if you have the following structure:
User1 (collection) --> userID (document)
Then you need to do the following:
Stream<DocumentSnapshot> getData()async*{
FirebaseUser user = await FirebaseAuth.instance.currentUser();
yield* Firestore.instance.collection('User1').where("userId", isEqualTo: user.uid).snapshots();
}
Then you can do:
body: Center(
child: Container(
padding: const EdgeInsets.all(10.0),
child: StreamBuilder<QuerySnapshot>(
stream: getData(),