Retrieving Data From Firestore in time - firebase

I have looked all over the internet for how to fix this problem and I can't find a solution anywhere. I am using flutter with firestore to make an app. I want to make it so when the user logins into the app at the top shows their name (simple right). I can get data from firestore:
Future<void> getName() async {
print("Attemping to get name!");
final firestoreInstance = await FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
await firestoreInstance.collection("Users").doc(uid).get().then((value) {
print("Name: " + value.data()["firstName"]);
info.firstName=((value.data()["firstName"]));
})
class info {
static String firstName;
}
but it comes in too late so the app just says "Welcome back" As you can see here and not "Welcome back, Connor" As seen here
When I look in the console the function does run but the program doesn't wait for it and continues resulting in a null.
Thanks you
EDIT as requested UI code:
class Home extends StatelessWidget {
final DatabaseReference = FirebaseDatabase.instance;
final FirebaseAuth auth = FirebaseAuth.instance;
static String firstName;
static String lastName;
static String email;
static String companyName;
static bool isNewAccount = false;
static String name = "Welcome back";
Home();
#override
Widget build(BuildContext context) {
final User user = auth.currentUser;
final uid = user.uid;
final ref = DatabaseReference.reference();
if (isNewAccount == true) {
userSetup(firstName, lastName, email, companyName);
isNewAccount = false;
}
getName(); //does get the name from the database but name will error out as it doesn't get the name fast enough (or that's what I think)
name= "Welcome back, "+info.firstName;
return WillPopScope(
onWillPop: () async => false,
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.cyan,
body: SingleChildScrollView(
child: Container(
margin:
EdgeInsets.only(top: MediaQuery.of(context).size.height / 16),
child: Column(
children: [
Container(
margin: EdgeInsets.only(bottom: 10),
child: Text(
name,
textAlign: TextAlign.center,
style: new TextStyle(
color: Colors.white,
fontSize: MediaQuery.of(context).size.width / 16,
),
),
),
Container(
width: 260,
height: 125,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Text(
"CHECK-IN",
style: new TextStyle(
color: Colors.white,
fontSize: 40.0,
),
),
color: Colors.grey[850],
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Checkin()));
},
),
),
Container(
width: 260,
height: 140,
padding: EdgeInsets.only(top: 20),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Text(
"CHECK-OUT",
style: new TextStyle(
color: Colors.white,
fontSize: 38.0,
),
),
color: Colors.grey[850],
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Checkout()));
},
),
),
Container(
margin: EdgeInsets.only(top: 55),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(right: 20),
child: Text(
"Sign out: ",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
Container(
child: RaisedButton(
child: Text(
"SIGN OUT",
style: new TextStyle(
fontSize: 14.0,
color: Colors.white,
),
),
color: Colors.grey[700],
onPressed: () {
context.read<AuthenticationService>().signOut();
//return MyApp();
},
),
)
],
),
),
Container(
margin: EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(right: 20),
child: Text(
"View Stats: ",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
Container(
child: RaisedButton(
child: Text(
"STATS",
style: new TextStyle(
fontSize: 14.0,
color: Colors.white,
),
),
color: Colors.grey[700],
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Stats()));
},
),
),
],
),
),
Container(
margin: EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.only(right: 20),
child: Text(
"View Profile: ",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
Container(
child: RaisedButton(
child: Text(
"PROFILE",
style: new TextStyle(
fontSize: 14.0,
color: Colors.white,
),
),
color: Colors.grey[700],
onPressed: () {
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Stats()));*/
},
),
),
],
),
),
Container(
width: 240,
height: 55,
margin: EdgeInsets.only(
top: MediaQuery.of(context).size.height / 12),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Text(
"EMERGENCY REPORT",
style: new TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
color: Colors.grey[700],
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => EmergencyReport()));
},
),
),
],
),
),
),
),
),
);
}
static getAccountDetails(
String firstName1, String lastName1, String email1, String companyName1) {
firstName = firstName1;
lastName = lastName1;
email = email1;
companyName = companyName1;
isNewAccount = true;
}
static getFirstName(String nameFirst) {
name = "Welcome back, "+nameFirst;
}
}

FutureBuilder<DocumentSnapshot>(
future: firestoreInstance.collection("Users").doc(uid).get(),
builder: (_,snap){
return snap.hasData ? Text(snap.data.data()["firstName"]):CircularProgressIndicator();
},)

You need to convert StatelessWidget into StatefullWidget.
After that you have to write this in initState method
void initState() {
super.initState();
getName().then((){
setState(() {
name= "Welcome back, "+info.firstName;
});
});
}

Related

Flutter Firebase Phone Authentication crashes the app on iOS when verifying

I am using phone authentication to link with google authentication. This implementation was working before but all of a sudden just crashing the app.
here is my full code
import 'package:FaithMeetsLove/controller/authentication.dart';
import 'package:another_flushbar/flushbar.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import 'package:pin_code_text_field/pin_code_text_field.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../constant/contact.dart';
import 'gender.dart';
class NumberOTP extends StatefulWidget {
NumberOTP({Key key}) : super(key: key);
#override
_NumberOTPState createState() => _NumberOTPState();
}
class _NumberOTPState extends State<NumberOTP> {
final phoneNumberInput = TextEditingController();
final otpNumberInput = TextEditingController();
String number123 = '';
PhoneNumber number = PhoneNumber(isoCode: 'AF');
String verificationId;
Future<bool> signIn() async {
try {
//!here is where phone auth start
final AuthCredential phoneCredential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: otpNumberInput.text,
);
final getuser =
await (auth.currentUser?.linkWithCredential(phoneCredential));
final user = getuser?.user;
await firestore.collection('users').doc(user?.uid).update({
'phoneNumber': user?.phoneNumber,
});
SharedPreferences pref = await SharedPreferences.getInstance();
await pref.setBool('phoneAuth', true);
return true;
} catch (e) {
return false;
}
}
Future<void> phoneAuth(BuildContext context) async {
try {
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verId) {
verificationId = verId;
};
final PhoneCodeSent codeSent = (String verId, [int forceCodeResend]) {
verificationId = verId;
setState(() {
next = false;
});
};
final PhoneVerificationCompleted verificationCompleted =
(phoneAuthCredential) {
print('verified');
};
final PhoneVerificationFailed verificationFailed = (error) async {
print('$error');
await Flushbar(
title: 'Error !!!',
message: 'Error Phone Verification $error',
duration: Duration(seconds: 3),
).show(context);
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: number123,
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout,
timeout: Duration(seconds: 10),
);
} catch (e) {
await Flushbar(
title: 'OTP Error !!!',
message: 'Error in OTP $e',
duration: Duration(seconds: 3),
).show(context);
}
}
bool next = true;
bool hasError = false;
bool checkIfIsValid = false;
Widget inputNumber() {
return Scaffold(
body: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).unfocus();
},
child: ProgressHUD(
child: Builder(
builder: (context) => Container(
padding: const EdgeInsets.all(17.0),
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Constants.color1,
Constants.color2,
],
),
),
child: Center(
child: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: CircleAvatar(
radius: 60,
backgroundColor: Colors.white.withOpacity(0.4),
child: Icon(
FontAwesomeIcons.phoneAlt,
color: Colors.white,
size: 30,
),
),
),
Flexible(
child: Text(
'Phone Number',
style: GoogleFonts.raleway(
textStyle: TextStyle(
fontSize: 35,
color: Colors.white,
),
),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Text(
'Input Your Phone Number that will be Associated with your account',
textAlign: TextAlign.center,
style: GoogleFonts.raleway(
textStyle: TextStyle(
fontSize: 15,
color: Colors.white,
),
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0, horizontal: 180),
child: Divider(
thickness: 5,
color: Colors.white.withOpacity(0.6),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: InternationalPhoneNumberInput(
maxLength: 11,
inputDecoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.circular(15),
),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.circular(15),
),
hintText: 'Number',
hintStyle: TextStyle(
color: Colors.white,
),
),
textStyle:
TextStyle(color: Colors.white, fontSize: 25),
onInputChanged: (PhoneNumber number) {
number123 = number.phoneNumber;
print(number.phoneNumber);
},
onInputValidated: (bool value) {
checkIfIsValid = value;
print(value);
},
selectorConfig: SelectorConfig(
selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
),
ignoreBlank: false,
autoValidateMode: AutovalidateMode.disabled,
selectorTextStyle:
TextStyle(color: Colors.white, fontSize: 18),
initialValue: number,
textFieldController: phoneNumberInput,
formatInput: false,
keyboardType: TextInputType.numberWithOptions(
signed: true, decimal: true),
inputBorder: OutlineInputBorder(),
onSaved: (PhoneNumber number) {
print('On Saved: $number');
},
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Container(
height: 60,
child: TextButton(
onPressed: () async {
final progress = ProgressHUD.of(context);
progress?.showWithText('Sending OTP');
try {
if (checkIfIsValid) {
await phoneAuth(context);
progress?.dismiss();
await Flushbar(
title: 'OTP',
message: 'OTP Sent',
duration: Duration(seconds: 3),
).show(context);
} else {
progress?.dismiss();
await Flushbar(
title: 'Ops!',
message:
'Correct Your Phone Number........',
duration: Duration(seconds: 3),
).show(context);
}
} catch (e) {
await Flushbar(
title: 'Ops!',
message: '$e',
duration: Duration(seconds: 3),
).show(context);
}
},
child: Icon(
Icons.check,
color: Colors.red,
),
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(18.0),
side: BorderSide(color: Colors.red)),
backgroundColor: Colors.white,
),
),
),
),
],
),
)
],
),
),
),
),
),
),
),
);
}
Widget inputOtp() {
return Scaffold(
body: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).unfocus();
},
child: ProgressHUD(
child: Builder(
builder: (context) => Container(
padding: const EdgeInsets.all(17.0),
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Constants.color1,
Constants.color2,
],
),
),
child: Center(
child: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: CircleAvatar(
radius: 60,
backgroundColor: Colors.white.withOpacity(0.4),
child: Icon(
Icons.phone_android_rounded,
color: Colors.white,
size: 60,
),
),
),
Flexible(
child: Text(
'We sent a code',
style: GoogleFonts.raleway(
textStyle: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Text(
'Enter the Secure OTP that was sent to the associated number',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0, horizontal: 180),
child: Divider(
thickness: 5,
color: Colors.white.withOpacity(0.6),
),
),
Container(
child: PinCodeTextField(
autofocus: false,
controller: otpNumberInput,
hideCharacter: false,
highlight: true,
highlightColor: Colors.blue,
defaultBorderColor: Colors.black,
hasTextBorderColor: Colors.green,
highlightPinBoxColor: Colors.white,
maxLength: 6,
hasError: hasError,
//maskCharacter: "😎",
onTextChanged: (text) {
setState(() {
hasError = false;
});
},
onDone: (text) {
print("DONE $text");
print("DONE CONTROLLER ${otpNumberInput.text}");
},
pinBoxWidth: 50,
pinBoxHeight: 50,
hasUnderline: false,
wrapAlignment: WrapAlignment.spaceAround,
pinBoxDecoration:
ProvidedPinBoxDecoration.roundedPinBoxDecoration,
pinTextStyle:
TextStyle(fontSize: 15.0, color: Colors.black),
pinTextAnimatedSwitcherTransition:
ProvidedPinBoxTextAnimation.scalingTransition,
pinTextAnimatedSwitcherDuration:
Duration(milliseconds: 300),
highlightAnimationBeginColor: Colors.black,
highlightAnimationEndColor: Colors.white12,
keyboardType: TextInputType.number,
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 18.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Container(
height: 60,
child: TextButton(
onPressed: () async {
final progress = ProgressHUD.of(context);
progress?.showWithText('Please wait');
try {
final isSiging = await signIn();
if (isSiging) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SelectGender(),
),
);
progress?.dismiss();
} else {
progress?.dismiss();
await Flushbar(
title: 'Ops!',
message:
'Number already use or Wrong OTP',
duration: Duration(seconds: 3),
).show(context);
}
} catch (e) {
progress?.dismiss();
await Flushbar(
title: 'Ops!',
message: '$e',
duration: Duration(seconds: 3),
).show(context);
}
},
child: Icon(
Icons.check,
color: Colors.red,
),
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(18.0),
side: BorderSide(color: Colors.red)),
backgroundColor: Colors.white,
),
),
),
),
],
),
)
],
),
),
),
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return next ? inputNumber() : inputOtp();
}
Widget makeInput({
hintText,
TextEditingController controller,
}) {
return TextField(
controller: controller,
textAlign: TextAlign.center,
cursorColor: Colors.white,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
hintText: hintText,
filled: true,
fillColor: Colors.white.withOpacity(0.3),
hintStyle: TextStyle(color: Colors.white.withOpacity(0.7)),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.red.withOpacity(0.2), width: 1.0),
borderRadius: BorderRadius.circular(15),
),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.red.withOpacity(0.2), width: 1.0),
borderRadius: BorderRadius.circular(15),
),
),
style: TextStyle(
fontSize: 25,
color: Colors.white,
),
);
}
}
here is info.plist
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.39...4890211-klbqki2me0m8fjccmb......</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fb368586070589462</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FacebookAppID</key>
<string>368586070589462</string>
<key>FacebookDisplayName</key>
<string>FaithMeetsLove</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fbapi20130214</string>
<string>fbapi20130410</string>
<string>fbapi20130702</string>
<string>fbapi20131010</string>
<string>fbapi20131219</string>
<string>fbapi20140410</string>
<string>fbapi20140116</string>
<string>fbapi20150313</string>
<string>fbapi20150629</string>
<string>fbapi20160328</string>
<string>fbauth</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
i have even run on debug still yet no error printed out. Immediately i click to verify the number it will just crash the app.

Retrieve same key data from Firebase on all pages

So the problem is I'm trying to retrieve this data from the Firebase database, where each case study
represent one key of data, and what I get is the same data of the first key on all the case study pages.
Data on the Firebase:
List of Case studies Page:
enter image description here
Case Study Page:
These are two different case studies yet have the same data.
enter image description here
enter image description here
I used Animated List at the beginning to retrieve the data but it gave me the same problem, so I
followed a Youtube Tutorial and used another way but the problem remains. I know I need to pass a key when the button is clicked to link each case study with its key but I'm not sure how.
Here is the code for more clarification:
stu_case_study_view.dart
Case Study Page
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:virtulab/Model/stu_case_study_model.dart';
import 'package:virtulab/functions/database.dart';
import 'package:virtulab/widgets/back_button.dart';
class CaseStudyView extends StatefulWidget {
final String csKey;
CaseStudyView({this.csKey});
#override
State<StatefulWidget> createState() {
return _CaseStudyView();
}
}
class _CaseStudyView extends State<CaseStudyView> {
bool _loading = false;
List<CaseStudyModel> caseStudyList = [];
final _formKey = GlobalKey<FormState>();
final question1Controller = TextEditingController();
final question2Controller = TextEditingController();
final question3Controller = TextEditingController();
final question4Controller = TextEditingController();
final question5Controller = TextEditingController();
DatabaseReference caseStudyInfo;
#override
void initState() {
super.initState();
caseStudyInfo = firebaseref.child('case_study');
caseStudyInfo.once().then((DataSnapshot snap) {
var keys = snap.value.keys;
var data = snap.value;
caseStudyList.clear();
for (var key in keys) {
CaseStudyModel csList = new CaseStudyModel(
data[key]['title'],
data[key]['description'],
data[key]['body'],
data[key]['question1'],
data[key]['question2'],
data[key]['question3'],
data[key]['question4'],
data[key]['question5'],
);
caseStudyList.add(csList);
}
setState(() {
print('Length : $caseStudyList.length');
});
});
}
#override
Widget build(BuildContext context) {
return
Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Case Study'), //Temp data
backgroundColor: Colors.deepPurple,
),
body: Container(
child: caseStudyList.length == 0
? new Text('No Case Studies Uploaded')
: new ListView.builder(
itemCount: caseStudyList.length,
itemBuilder: (_, index) {
return _caseStudy(
caseStudyList[index].title,
caseStudyList[index].description,
caseStudyList[index].body,
caseStudyList[index].question1,
caseStudyList[index].question2,
caseStudyList[index].question3,
caseStudyList[index].question4,
caseStudyList[index].question5,
);
}),
),
);
}
_showAlertDialog(BuildContext context) {
Widget cancelButton = FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context, rootNavigator: true).pop());
Widget submitButton = FlatButton(
child: Text('Submit'),
onPressed: () {
if (_formKey.currentState.validate()) {
firebaseref.child('case_study').push().set({
"question1": question1Controller.text,
"question2": question2Controller.text,
"question3": question3Controller.text,
"question4": question4Controller.text,
"question5": question5Controller.text,
});
Navigator.of(context, rootNavigator: true).pop();
Navigator.pop(context);
}
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text('Alert'),
content: Text('Are you sure you want to submit?'),
actions: [
cancelButton,
submitButton,
],
);
// show the dialog
showDialog(
context: context,
// barrierDismissible: false,
builder: (BuildContext cxt) {
return alert;
},
);
}
Widget _caseStudy(
String title,
String description,
String body,
String question1,
String question2,
String question3,
String question4,
String question5) {
return _loading
? Container(
child: Center(
child: CircularProgressIndicator(),
),
)
: Container(
padding: EdgeInsets.fromLTRB(10, 0, 10, 10),
child: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: <Widget>[
Text(
title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
height: 2,
color: Colors.deepPurple),
),
Divider(),
Text(
'Description:',
textAlign: TextAlign.left,
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text(
description,
textAlign: TextAlign.left,
maxLines: null,
),
),
Text(
'Case Study:',
textAlign: TextAlign.left,
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text(
body,
textAlign: TextAlign.left,
maxLines: null,
),
),
Divider(),
Text(
'Questions:',
textAlign: TextAlign.left,
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'1/ ' + question1,
textAlign: TextAlign.left,
maxLines: null,
),
],
)),
TextFormField(
controller: question1Controller,
validator: (v) =>
v.isEmpty ? 'Enter Your Answer' : null,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Write Your Answer Here',
),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'2/ ' + question2,
textAlign: TextAlign.left,
maxLines: null,
),
],
)),
TextFormField(
controller: question2Controller,
validator: (v) =>
v.isEmpty ? 'Enter Your Answer' : null,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Write Your Answer Here',
),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'3/ ' + question3,
textAlign: TextAlign.left,
maxLines: null,
),
],
)),
TextFormField(
controller: question3Controller,
validator: (v) =>
v.isEmpty ? 'Enter Your Answer' : null,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Write Your Answer Here',
),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'4/ ' + question4,
textAlign: TextAlign.left,
maxLines: null,
),
],
)),
TextFormField(
controller: question4Controller,
validator: (v) =>
v.isEmpty ? 'Enter Your Answer' : null,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Write Your Answer Here',
),
),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'5/ ' + question5,
textAlign: TextAlign.left,
maxLines: null,
),
],
)),
TextFormField(
controller: question5Controller,
validator: (v) =>
v.isEmpty ? 'Enter Your Answer' : null,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Write Your Answer Here',
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: <Widget>[
FloatingActionButton.extended(
onPressed: () {
_showAlertDialog(context);
},
label: Text(
"Submit",
style: TextStyle(
fontWeight: FontWeight.bold),
),
backgroundColor: Colors.amber,
),
],
))),
),
]),
)));
}
}
stu_case_study_model.dart
class CaseStudyModel {
String title,
description,
body,
question1,
question2,
question3,
question4,
question5;
CaseStudyModel(this.title, this.description, this.body, this.question1,
this.question2, this.question3, this.question4, this.question5);
}
stu_caseStudies_list.dart
List of Case studies Page
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:virtulab/functions/Student/class_case_study_list.dart';
import 'package:virtulab/functions/database.dart';
import 'package:virtulab/student/stu_case_study_view.dart';
class CaseStudiesList extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _CaseStudiesList();
}
}
class _CaseStudiesList extends State<CaseStudiesList> {
Query _caseStudyTitle;
#override
void initState() {
super.initState();
_caseStudyTitle = firebaseref.child('case_study');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Case Studies'),
backgroundColor: Colors.deepPurple,
),
body: FirebaseAnimatedList(
query: _caseStudyTitle,
defaultChild: Center(child: CircularProgressIndicator()),
itemBuilder: (BuildContext context, snapshot,
Animation<double> animation, int index) {
Map caseStudy = snapshot.value;
caseStudy['key'] = snapshot.key;
return _caseStudyList(caseStudy: caseStudy);
},
),
);
}
Widget _caseStudyList({Map caseStudy}) {
return Column(
children: [
Card(
child: InkWell(
onTap: () {},
child: Container(
margin: EdgeInsets.symmetric(vertical: 10),
// padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
// height: 70,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(
Icons.description_sharp,
),
SizedBox(width: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
caseStudy['title'],
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
height: 2,
color: Colors.deepPurple),
),
],
),
],
),
ElevatedButton(
onPressed: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CaseStudyView(
//csKey: caseStudy['key'],
),
),
)
},
child: Text('Start'),
// color: Colors.amber,
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.amber))),
],
),
),
SizedBox(height: 5),
],
),
),
),
),
],
);
}
}
This is my graduation project and I sincerely appreciate your help. Thank you.

How to add "this user/account does not exist" error in Flutter, using Firebase?

I am trying to make a login page in Flutter. I have used Firebase as well for user authentication and logging in. The problem is, while I can login successfully with the correct information, I am unable to display anything like a pop up error box or message that the account does not exist. This is my code :
class _LoginPageState extends State<LoginPage> {
String _email, _password;
final auth = FirebaseAuth.instance;
bool hidepwd = true;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
brightness: Brightness.light,
backgroundColor: Colors.transparent,
elevation: 0,
leading: Container(
margin: EdgeInsets.all(5),
width: 50,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color(0xffe9eefa),
),
child: IconButton(
onPressed: (){Navigator.pop(context);},
icon: Icon(
Icons.keyboard_arrow_left_rounded,
color: Color(0xff2657ce),
),
),
),
),
body: ListView(
children: <Widget>[
Container(
child: IconButton(
icon: Icon(
Icons.account_circle_rounded,
color: Color(0xff2657ce),
size:100,
),
),
),
SizedBox(height: 50,),
Expanded(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
padding: EdgeInsets.only(right: 240),
child: Text('Email Address', style: TextStyle(
fontSize: 15,),),
),
SizedBox(height: 10,),
Container(
padding: EdgeInsets.symmetric(vertical: 2, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.grey.withOpacity(0.2),
),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'Email',
),
onChanged: (value) {
setState(() {
_email = value.trim();
});
},
),
),
SizedBox(height: 20,),
Container(
padding: EdgeInsets.only(right: 270),
child: Text('Password', style: TextStyle(
fontSize: 15,
),),
),
SizedBox(height: 10,),
Container(
padding: EdgeInsets.symmetric(vertical: 2, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.grey.withOpacity(0.2),
),
child: Row(
children: <Widget>[
Expanded(
child: TextFormField(
obscureText: hidepwd,
decoration: InputDecoration(hintText: 'Password'),
onChanged: (value) {
setState(() {
_password = value.trim();
});
},
),
),
Container(
height: 50,
width: 50,
child: IconButton(
onPressed: togglepwdVisibility,
icon: IconButton(
icon: hidepwd == true ? Icon(
Icons.visibility_off
): Icon(Icons.visibility),
),
),
)
],
),
),
SizedBox(height: 20,),
RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
color: Color(0xff5178D7),
child: Text("Log In", style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 15
),),
onPressed: (){
auth.signInWithEmailAndPassword(email: _email, password: _password).then((_){
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => frontpage()));
});
}
),
SizedBox(height: 20,),
Container(
child: Center(
child: Text('---- or ----'),
),
),
SizedBox(height: 20,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account? "),
InkWell(
onTap: openSignUpPage,
child: Text("Sign Up", style: TextStyle(
color: Color(0xff1A3C90),
fontWeight: FontWeight.w700
),),
)
],
)
],
),
),
),
],
),
);
}
Any ideas/suggestions on what I could add or change in my code to have that error message included when I am unable to login overall?
In your login onPressed: (){ ... }, catch the FirebaseAuthException.
Source: https://firebase.flutter.dev/docs/auth/usage/#sign-in
try {
UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: "barry.allen#example.com",
password: "SuperSecretPassword!"
);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
If you need alerts to pop on each login error you can try using the following function but only if you are using TextEdittingController:
signIn() async {
if (_loginFormKey.currentState!.validate()) {
_loginFormKey.currentState!.save();
try {
await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text)
.then((currentUser) => FirebaseFirestore.instance
.collection("users")
.doc(currentUser.user!.uid)
.get()
.then((conext) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage())))
.catchError((err) => print(err)));
} on FirebaseAuthException catch (error) {
if (error.code == 'user-not-found') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Auth Exception!"),
content: Text("This User Does Not Exist."),
actions: <Widget>[
Row(
children: [
ElevatedButton(
child: Text("Sign In Again"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
)
],
);
});
} else if (error.code == 'wrong-password') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Auth Exception!"),
content: Text("The Password Entered is Invalid."),
actions: <Widget>[
Row(
children: [
ElevatedButton(
child: Text("Sign In Again"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
)
],
);
});
}
}
}
}

How to retrive a doc from firestore with its ID with flutter

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}",
),
],
),
),
),
],
),
),
),
);
}
}

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