How to display any Data from Firestore using ternary operator - firebase

I was trying to fetch data from firebase and I wanted to show an Icon of Instagram only if there is any data available in the firebase collection. I used the following method to fetch the data from firebase
StreamBuilder(
stream: Firestore.instance.collection("aboutpage").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: Center(
child: SpinKitThreeBounce(
color: Colors.lightBlueAccent,
size: 30.0,
),
),
);
} else {
return Container(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot aboutpage = snapshot.data.documents[index];
return Column(
There is no Problem while retrieving data from firebase. Probleme is when I want to display an Instagram icon if the data is available in firebase is used ternary operator but did not work for me
"${aboutpage["name"]}" == null
? Container()
: IconButton(Icon: Icons.instagram),
onPressed: (}{}
),
I also tried using "${aboutpage["name"]}".isEmpty but dint work for me. So, How can I fetch data only if its available and if empty return empty Container?

Change the condition from "${aboutpage["name"]}" == null to aboutpage is Map && aboutpage["name"] == null.

Related

Firebase doesn't work cause of null-safety (DART/FLUTTER)

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.

How to show data in Flutter from Firestore collection based on the value in the array?

I need to remove documents - reviews/posts - from the stream, which the user has hidden. When a user decides to hide the post, the post collection's post-doc creates an array 'hidingUserId' of userIDs that has hidden it. refer to the pic, pls.
now I need to remove the post where the array 'hidingUserId' contains the currentUserId. I have tried the following, but it does not display errors in the log and it does not display the posts. Just circular progress circling on the screen.
Stream streams = postRef
.orderBy('stars', descending: false)
.orderBy('timestamp', descending: true)
.snapshots();
#override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
padding: EdgeInsets.symmetric(horizontal: 10.0),
children: [
StreamBuilderWrapper(
shrinkWrap: true,
stream: streams.where((event) => event.data()['hidingUserId']
== null
|| event.data()['hidingUserId'].contains(!currentUserId()) ?
streams.forEach((event) => print(event))
: Container(
child: Center(
child: Text('Nothing to show'),))),
physics: NeverScrollableScrollPhysics(),
itemBuilder: (_, DocumentSnapshot snapshot) {
internetChecker();
Review posts = Review.fromJson(snapshot.data());
return posts.postId != null
? Padding(
padding: const EdgeInsets.only(bottom: 12.0),
child: Posts(post: posts),
)
: Container(
child: Center(
child: Text('Nothing to show'),
),
);
},
),
],
);
}
am new to Firestore, and I can't find the information I need. help appreciated very much! Thanks!

ListTile Flutter

is there any way I can add more value to the ListTile in the code as I am trying to use ListTile to call the value of data in FireCloud. As for now, I can only call 2 of the data that is in the document. Any help would be much appreciated on how to call multiple data in FireCloud and display it.
return Container(
child: Card(
child: ListTile(
title: Text(widget.post.data["Address"]),
subtitle: Image.network(widget.post.data["Picture"],
),
),
),
);
Check out this example that will work for you :
ListView.builder(
itemCount: /* snapshot.data.length */,
itemBuilder: (_, index) {
return GestureDetector(
onTap: (){
//navigateToDetail(snapshot.data[index]),
},
child: Card(
child: Column(
children: <Widget>[
Text('your address'),
Text('you and another data')
],
),
),
);
}),
You ca align it in the way you want.
Let me know if it works
Use ListView.builder constructor, this will help you fetch the total data from the FireCloud. You can use it like this:
Two major things required, these are:
itemCount: Keeps the count of the data you are going to fetch from the FireCloud. Store the coming data into a list, and then pass it into this key
itemBuilder: Builds your view which will have the data used from the passed item in the itemCount
Reference:
ListView.builder(
itemCount: listItems.length,
itemBuilder: (BuildContext ctxt, int index){
// your_view
}
)
For more reference, please refer to this Medium Article on how to get started: Flutter: Displaying Content using ListView.builder

Flutter Firebase ListView - Slow Refreshes

I created a ListView that populates from a Firebase collection by using a StreamBuilder widget. It takes some time for the ListView to populate because I'm running tasks (HTTP requests) for each item of the Firebase collection and then displaying the result in the list.
When I navigate away from the page with the ListView and then return to the page (using PageView), the ListView appears to refresh entirely instead of using the last seen version. So there is a ~5 second circular progress indicator while the list re-populates every time the page is re-opened.
Questions:
What is the best way to make this ListView not complete a full 5
second refresh every time the page is re-opened? Can it use the last seen version and only update when items are added to the firebase collection?
If I were to remove the tasks (HTTP requests) that need to be ran on each item of the collection and instead simply show values directly from the Firebase collection, should the refresh time be fast enough that it is not a problem?
Is it best to create a local database (using sqflite) that syncs with the Firebase collection to prevent slow refreshes?
Code:
class AccountsPage extends StatefulWidget {
#override
_AccountsPageState createState() => _AccountsPageState();
}
class _AccountsPageState extends State<AccountsPage> {
User user;
Widget _buildListItem(BuildContext context, DocumentSnapshot document, String uuid) {
// get data from firebase
String token = document.data.values.toList()[0];
// For current document/token, make an HTTP request using the token and return relevant data
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: FutureBuilder(
future: anHTTPrequest(token, uuid),
builder: (context, projectSnap) {
if (projectSnap.connectionState == ConnectionState.none ||
!projectSnap.hasData || projectSnap.data.length == 0) {
return Container();
}
return ListView.builder(
shrinkWrap: true,
itemCount: projectSnap.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(projectSnap.data[index]),
);
},
);
},
),
)],
);
}
#override
Widget build(BuildContext context) {
final container = StateContainer.of(context);
user = container.user;
return Container(
child: Scaffold(
body: Column(
children: <Widget>[
new Flexible(
child: StreamBuilder(
stream: Provider.of(context).collectionRef.document(user.uuid).collection('tokens').snapshots(),
builder: (context, snapshot){
if (!snapshot.hasData){
return Container(
child: Center(
child: Text("No data")
)
);
}
return ListView.builder(
padding: EdgeInsets.all(8.0),
reverse: false,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, int index) {
return _buildListItem(context, snapshot.data.documents[index], user.uuid);
}
);
}
)
),
]
),
),
);
}
}

Map in GridView

I'm with a problem making a GridView where the children are a array of images from firebase, i've already tried a lot of things like changing the List type, changing ImageNetwork to NetworkImage, making map, etc, but it's always giving me the same error "The method 'map' was called on null".
return Material(
child: GestureDetector(
child: FutureBuilder(
future: Firestore.instance.collection("images-lessons").document("teste").collection("images-teste").getDocuments(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator(),);
}
else {
return GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: imageLessonData.imageL.map((url){
return Image.network(url);
}).toList() ,);
}
}),
),
);

Resources