"Read Data from Firebase", not working after update 2.8.1 - firebase

Solution
Added code before return
if (!snapshot.hasData) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(
color: Colors.red,
)),
);
}
important! - if (!snapshot.hasData)
I try show data from FireBase, I have DB on Firestore.
I updated today Flutter (2.8.0 -> 2.8.1) , code worked before update
My code
import 'package:cloud_firestore/cloud_firestore.dart';
class FireService extends StatefulWidget {
#override
_FireServiceState createState() => _FireServiceState();
}
class _FireServiceState extends State<FireService> {
final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance
.collection('chats/uHdJ4WvHjvphsBUpb9yk/visits')
.snapshots();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Visits'),
),
body: StreamBuilder(
stream: _usersStream,
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Card(
child: ListTile(
title: Text(
data['company'],
style: TextStyle(fontSize: 19, color: Colors.black),
),
subtitle: Text(
data['number_visit'].toString(),
),
leading: Icon(
Icons.local_offer,
size: 40,
color: Colors.red,
),
),
);
}).toList(),
);
}),
);
}
}
After starting an error occurs
enter image description here
Please, write a new code so I understand the error. Thanks
UPD 1.
I tried an option
children: snapshot.data?.docs.map((DocumentSnapshot document) {
a new mistake - the whole block of code with a red line
enter image description here

Your line snapshot.data!.docs.map should use the nullish coalescing instead of the !.
The line should be:
snapshot.data?.docs.map
data?. will gracefully break if data is null

Related

update field of a document in firebase from a listview flutter

I want to show list of documents from Firestore ,
and also i want if i click the button accept , I tried to show all the documents in a listview but i have a problem with the button , i want that the statut of the document change from "en cours" to "accept" but i can't get the id of the document to update the data once the text is cliqued .
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../rounded_button.dart';
class DemandeList extends StatelessWidget {
final db = FirebaseFirestore.instance;
String? Key ;
DemandeList({this.Key});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Listes des demandes"),
centerTitle: true,
),
body: StreamBuilder<QuerySnapshot>(
stream: db.collection('ambulance')
.where("etat", isEqualTo: "en cours")
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else
return ListView(
children: snapshot.data!.docs.map((doc) {
return Card(
child: ListTile(
trailing: Text("Accepter",
style: TextStyle(
color: Colors.green,fontSize: 15
),
),
title: new Text(doc['id']) ,
subtitle: new Text(doc['etat']),
onTap: () => {
}
),
);
}).toList(),
);
},
),
);
}
}
I don't see methods inside onTap so I'm just assuming but if you want to access documentID you should write doc.id instead of doc["id"].
hope this is what you are seeking for.
for updating the document when text is tapped, you can write as below
onTap:()=>db.collection('ambulance').doc(doc.id).update({etat:'accept'});

Error: The argument type 'Stream<PostsRecord>' can't be assigned to the parameter type 'Record'

New to flutter here (and coding in general) but have an issue that I cannot figure out to solve. I am navigating to a page based off of a variable and need to pass in a Record. However, I cannot figure out how to pass a Record from the reference already on the page (postReference). I only want to read this document if the button is pressed also. Using Firebase/Firestore as the backend. Any help is greatly appreciated!
Error
Error: The argument type 'Stream' can't be assigned to the parameter type 'PostsRecord'.
Code snippet below. I cannot figure out how to properly query the record to then pass to the Widget Builder.
class NotificationPageWidget extends StatefulWidget {
const NotificationPageWidget({Key key}) : super(key: key);
#override
_NotificationPageWidgetState createState() => _NotificationPageWidgetState();
}
class _NotificationPageWidgetState extends State<NotificationPageWidget> {
final scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: true,
title: Text(
'Notifications',
style: FlutterFlowTheme.title1,
),
),
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: StreamBuilder<List<UserNotificationsRecord>>(
stream: queryUserNotificationsRecord(
queryBuilder: (userNotificationsRecord) =>
userNotificationsRecord
.where('notifiedUsers',
arrayContains: currentUserReference)
.orderBy('notificationTime', descending: true),
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
if (!snapshot.hasData) {
return Center(
child: SizedBox(
width: 40,
height: 40,
child: CircularProgressIndicator(
color: FlutterFlowTheme.secondaryColor,
),
),
);
}
List<UserNotificationsRecord>
listViewUserNotificationsRecordList = snapshot.data;
return ListView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
itemCount: listViewUserNotificationsRecordList.length,
itemBuilder: (context, listViewIndex) {
final listViewUserNotificationsRecord =
listViewUserNotificationsRecordList[listViewIndex];
return InkWell(
onTap: () {
if (listViewUserNotificationsRecord.initialPageName == '/commentsPage') {
final postRef = PostsRecord.getDocument(listViewUserNotificationsRecord.postReference);
Navigator.push(context, MaterialPageRoute(builder: (context) => CommentsPageWidget(
activityRecord: postRef,
//This is where the error is occurring. Looking for a Record and not a Reference.
)
)
);
};
},
);
},
);
},
),
),
],
),
),
);
}
}

Flutter, Dart, Firestore: How can I send user data retrieved from firestore to a different screen?

I have a screen where a list of users are shown using stream builder to retrieve user data from firestore.
StreamBuilder(
stream: Collection
.where('WorkType', isEqualTo: widget.worktype)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Container(
height: 600,
child: ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
child: GestureDetector(
onTap: () {
//Navigate to Screen two
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
snapshot.data.docs[index].data()['Name'],
style: kRobotoSlab.copyWith(
fontSize: 20)),
Text(
snapshot.data.docs[index]
.data()['Address'],
style: kRobotoSlab.copyWith(
fontSize: 15),
),
Text(
snapshot.data.docs[index]
.data()['Phone Number'],
style: kRobotoSlab.copyWith(
fontSize: 15),
),
],
),
),
),
),
),
);
}),
);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return CircularProgressIndicator();
}
},
),
I want that once a user clicks on the card it will navigate to screen 2 which will show the user profile with the data retrieved from firestore
e.g. Card 1 : Name => Samia Address=> USA Number=> 4659848668 user will press on it and it will navigate to screen 2 with the information of Samia's.
How can I achieve it?
Let's say you call the new screen DetailScreen, you should have it take a Map of preferably an object of the items you want to display in it for example:
in the DetailScreen definition you can have:
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Item.
final User user;
// In the constructor, require a user.
DetailScreen({Key? key, required this.user}) : super(key: key);
#override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(user.name),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(user.address),
),
);
}
}
Then in your GestureDetector onTap method you can then do something like:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(user: users[index]),
),
);
Since you are not using a model like my example above, you can make the second screen accept a Map field, then you pass in snapshot.data.docs[index].data() as the value when you are navigating to it.
So this will now read:
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Item.
final Map user;
// In the constructor, require a user map.
DetailScreen({Key? key, required this.user}) : super(key: key);
#override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(user['Name']),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(user['Address']),
),
);
}
}
And while navigating you just do
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(user: snapshot.data.docs[index].data()),
),
);

Use Firestore to access images stored locally in a Flutter Project

I have Images of flags stored locally within my Flutter project assets/images folder i stored name of the images in firestore by opening a collection called "Languages" then set fields two fields
Languages [Collection] with auto id documents
1. Language_Image -> china.png [Fields]
2. Language_Name -> Chinese [Fields]
I want to generate a GridView of the flags (CircleAvatar) of every language and name of the language (Text)
I don't know how to go about the process to iterate through each document and get Language_Image and Language_Name data and build my GridView here is my code
`
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'Choose_Books.dart';
class ChooseLanguage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade300,
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text("Choose ChooseLanguage To Learn",
style: TextStyle(fontSize: ScreenUtil().setHeight(34)),
),
centerTitle: false,
),
body: ChooseLanguageBody(),
);
}
}
class ChooseLanguageBody extends StatefulWidget {
#override
_ChooseLanguageBodyState createState() => _ChooseLanguageBodyState();
}
class _ChooseLanguageBodyState extends State<ChooseLanguageBody> {
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance.collection('Language').snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: const Text('Loading events...'));
}return GridView.count(
// Create a grid with 3 columns.
crossAxisCount: 2,
children: List.generate(24, (index) {
return Center(
child: CupertinoButton(
child: Column(
children: <Widget>[
CircleAvatar(
maxRadius: 70.0,
backgroundImage: AssetImage('images/launguages/launguage${snapshot.data.documents[index]['Language_Image']}.png'),
),
Text(snapshot.data.documents[index]['Language_Image'], style: TextStyle(fontSize: ScreenUtil().setHeight(24), fontWeight: FontWeight.bold),
)
],
),
onPressed: () {Navigator.push(context, MaterialPageRoute(builder: (context) => ChooseBook()));},
),
);
}),
);
}
);
}
}
`
Is it the correct procedure am following or i messed up completely?
I think I found the Problem.
You missed adding the .data part.
Try this
snapshot.data.documents[index].data['Language_Image']
Hope this helps.!
(FYI-> your gig is lead to this problem)

Getting data from cloud firestore onto a listview in flutter

I am trying to pull data from a firebase cloud firestore collection (events) onto a list view, I’m not sure if I am implementing this correctly, when I run the app I get the error 'MappedListIterable' is not a subtype of type 'Widget'. This is my first time working with firebase cloud firestore and I could really use some help in better understanding this error.
This is where the list view is being initialized:
import 'package:flutter/material.dart';
import 'package:rallie_app/utils/event_summary.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class HomeList extends StatelessWidget {
Firestore db = Firestore.instance;
#override
Widget build(BuildContext context) {
return Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('events').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
// count of events
final int eventCount = snapshot.data.documents.length;
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState){
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
return new ListView.builder(
itemCount: eventCount ,
itemBuilder: (context, index) {
final DocumentSnapshot document = snapshot.data.documents[index];
return new EventSummary(document);
}
);
}
})
);
}
}
These are the list view items I wish to build :
import 'package:flutter/material.dart';
import 'package:rallie_app/model/events.dart';
import 'package:rallie_app/ui/detail/detail_page.dart';
import 'package:rallie_app/services/firestore_service.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
class EventSummary extends StatefulWidget {
//TODO: Event summary constructor with event model class initialized in it
final DocumentSnapshot event;
EventSummary(this.event);
#override
_EventSummaryState createState() => _EventSummaryState();
}
class _EventSummaryState extends State<EventSummary> {
#override
Widget build(BuildContext context) {
final userThumbnail = new Container(
margin: EdgeInsets.symmetric(vertical: 16.0),
alignment: FractionalOffset.centerLeft,
child: Hero(
tag: "user-image-${widget.event.data['id']}",
child: CircleAvatar(
backgroundImage: AssetImage(widget.event['event_poster_image']),
// backgroundColor: Colors.white,
maxRadius: 40.0,
),
),
);
final eventCardContent = Container(
margin: new EdgeInsets.only(left: 46.0),
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
color: new Color(0xFFFFFFFF),
borderRadius: new BorderRadius.circular(8.0),
image: DecorationImage(
image: AssetImage(widget.event.data['event_image']),
fit: BoxFit.fill,
),
),
);
Widget _eventValue(){
return Column(
children: <Widget>[
Container(
height: 150.0,
margin: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 24.0,
),
child: new Stack(
children: <Widget>[
eventCardContent,
userThumbnail,
],
),
),
Container(
margin: const EdgeInsets.only(left: 70.0, bottom: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
widget.event.data['event_name'],
textAlign: TextAlign.start,
),
Row(
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
widget.event.data['event_date'],
textAlign: TextAlign.start,
),
SizedBox(
width: 110,
),
IconButton(
icon: Icon(Icons.share),
splashColor: Colors.orange,
tooltip: 'Share button',
onPressed: () =>
debugPrint('Share btn tapped'),
)
],
),
Text(
widget.event.data['event_attending'],
textAlign: TextAlign.start,
),
],
),
)
],
);
}
return new GestureDetector(
onTap: () => Navigator.of(context).push(
new PageRouteBuilder(
pageBuilder: (_, __, ___) => new DetailPage(widget.event.data['id']),
transitionsBuilder:
(context, animation, secondaryAnimation, child) =>
new FadeTransition(opacity: animation, child: child),
),
),
child: StreamBuilder(
stream: Firestore.instance.collection('events').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('Loading data... Please wait');
return snapshot.data.documents.map(
(document) => _eventValue()
);
}),
);
}
}
In Your Code - Edit - widget.event['id'] to - widget.event.data['id'] & So On same with Other Places where you have Snapshot variable used...
As Per Documentation - DocumentSnapshot
A DocumentSnapshot contains data read from a document in your Cloud
Firestore database. The data can be extracted with .data()
widget.event is - DocumentSnapshot & to read the data you need to use .data Method.
Also the Error you are Getting is of Code :
child: StreamBuilder(
stream: Firestore.instance.collection('events').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('Loading data... Please wait');
return snapshot.data.documents.map(
(document) => Column(
......
Here Builder is Expecting a Widget as a return value not 'MappedListIterable' -
snapshot.data.documents.map(
(document) // is Wrong return value for StreamBuilder.
You Need Modify Your Code to return a widget here.

Resources