The getter 'data' was called on null. Receiver: null Tried calling: data - firebase

Tried signing up user with Firebase but got the above error instead, and the code is formatted in such a way that it should redirect the user to homepage after a successful signup.
My main.dart
import 'package:bedc_app/home_page.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:bedc_app/auth/login_page.dart';
void main() async{
//solution study
WidgetsFlutterBinding.ensureInitialized();
FirebaseAuth.instance.currentUser()
.then((FirebaseUser user) {
if(user != null){
Firestore.instance.collection('users').document(user.uid).get().then((DocumentSnapshot doc){
runApp(MyApp(true, doc));
});
return;
}
runApp(MyApp(false, null));
});
}
// void main() =>runApp(MyApp());
class MyApp extends StatelessWidget {
bool isLoggedIn;
DocumentSnapshot doc;
MyApp(this.isLoggedIn, this.doc);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Multifunctional bedc project App',
debugShowCheckedModeBanner: false,
home: isLoggedIn ? HomePage(userDoc: doc) : loginPage(),
);
}
}
My Signup_page.dart
import 'package:bedc_app/auth/login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:bedc_app/utils/constants.dart';
import '../home_page.dart';
class SignUpPage extends StatefulWidget {
#override
_SignUpPageState createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
String email, password;
bool isLoggedIn = false;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: ListView(
children: [
SizedBox(
height: 50,
),
Align(
alignment: Alignment.topCenter,
child: (
Image.asset(
'assets/bedclogo.jpg'
)),
),
SizedBox(
height: 100,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 26.0),
child: TextField(
decoration: InputDecoration(
hintText: 'email',
border: OutlineInputBorder(),
labelText: 'Email',
suffixIcon: Icon(Icons.email, color: Colors.green)
),
keyboardType: TextInputType.emailAddress,
onChanged: (String val){
email = val;
},
),
),
SizedBox(
height: 10,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 26.0),
child: TextField(
decoration: InputDecoration(
hintText: 'Password',
border: OutlineInputBorder(),
labelText: 'Password',
suffixIcon: Icon(Icons.lock, color: Colors.green)
),
obscureText: true,
obscuringCharacter: '!',
keyboardType: TextInputType.emailAddress,
onChanged: (String val){
password = val;
},
),),
SizedBox(
height: 5,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 26),
child: MaterialButton(
color: Color(0xFF88C540),
child: isLoading ? Container(
height: 24,
width: 24,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
strokeWidth: 2,
)
):Text(
'SignUp'.toUpperCase(),
style: TextStyle(fontWeight: FontWeight.bold),
),
onPressed: (){
checkUserInput();
},
),
),
SizedBox(
height: 10,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: RichText(
text: TextSpan(
text: 'Already have an Account ?',
style: TextStyle(color: Colors.black),
children: [
TextSpan(
text: 'Login here',
style: TextStyle(color: Colors.blue),
recognizer: TapGestureRecognizer()..onTap = (){
Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_) => loginPage()));
},
)
]
)),
)
],
));
}
//SIGNUP FUNCTION USING FIREBASE
bool isLoading = false;
signUpUserWithFirebase(){
FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password
).then((AuthResult result){
//Authresult cant be stored to string.....
storeUserDataToFirestore(result.user.uid);
if(result.user.uid != null){
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => HomePage()));
}
}).catchError((e){
print(e);
isLoading = false;
setState(() { });
});
}
//storeUserDataToFirestore
storeUserDataToFirestore(String userId){
Map<String, dynamic> userData = Map<String, dynamic>();
userData = {
Constants.USERNAME: '#username',
Constants.USER_ID: userId,
Constants.EMAIL : email,
Constants.ACCOUNT_NUM : '00000000',
Constants.IS_ADMIN: false,
Constants.PROFILE_IMAGE: '',
Constants.PROFILE_IMAGE_THUMB: '',
};
CollectionReference usersRef = Firestore.instance.collection(Constants.USERS_COLLECTION);
usersRef.document(userId).setData(userData).then((_){
isLoading = false;
setState(() { });
}).catchError((e){
print(e);
});
}
//FUNCTION TO CHECK USER ENTRY
checkUserInput(){
isLoading = true;
setState(() { });
if(email == null || email.isEmpty){
print('Enter email');
isLoading = false;
setState(() { });
return;
}
if(password == null || email.isEmpty){
print('Enter password');
isLoading = false;
setState(() { });
}
//SIGNUP THE USER
signUpUserWithFirebase();
}
getUserData(String UserId){
Firestore.instance.collection(Constants.USERS_COLLECTION)
.document(UserId)
.get().then((DocumentSnapshot userDoc){
Navigator.of(context).pop();
Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_) => HomePage(userDoc: userDoc)));
}).catchError((e){
print(e);
});
}
}
My Home_page.dart
import 'dart:ui';
import 'package:bedc_app/auth/login_page.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:bedc_app/auth/signup_page.dart';
import 'model/user.dart';
User currentUser;
class HomePage extends StatefulWidget {
DocumentSnapshot userDoc;
HomePage({this.userDoc,});
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//user cant access this page unless logged in
bool userIsLoggedIn = true;
#override
void initState() {
// TODO: implement initState
super.initState();
currentUser = User.fromSnapshot(widget.userDoc);
}
//HERE IS BUILDING PROFILE IMAGE
Widget buildProfileImage(){
if(currentUser.profileImage == ''){
return CircleAvatar(
backgroundColor: Colors.white70,
radius: 20,
child: Icon(Icons.person, size: 30),
);
}else{
return CircleAvatar(
backgroundImage: NetworkImage(currentUser.profileImage),
);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.brown,
title: Text('Homepage'),
),
body: ListView(
children: [
SizedBox(height: 20),
Align(
alignment: Alignment.topRight,
child: (
Image.asset(
'assets/bedclogo.jpg',
scale: 2,
)),
),
ListTile(
title: Text(currentUser.username, style: TextStyle(color: Colors.brown, fontWeight: FontWeight.bold),),
leading: buildProfileImage(),
),
SizedBox(height: 30),
//CAPTURE METER READING UI
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: GestureDetector(
onTap: (){
//print(currentUser.isAdmin);
},
child: Row(
children: [
//CAPTURE METR READING
Container(
width: 100,
height: 100,
color: Colors.green,
child: Align(
alignment: Alignment.center,
child: (
Image.asset(
'assets/meterIcon.png',
scale: 3,
)),
),
),
Container(
width: 100,
height: 100,
child: Align(
alignment: Alignment.center,
child: Text('Capture Meter Reading'.toUpperCase()),
),
),
],
),
),
),
SizedBox(height: 30),
//UPDATE PROFILE UI DESIGN
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: GestureDetector(
onTap:(){
//print(currentUser.isAdmin);
},
child: Row(
children: [
Container(
width: 100,
height: 100,
color: Colors.green,
child: Align(
alignment: Alignment.center,
child: (
Image.asset(
'assets/profileAvatar.png',
scale: 3,
)),
),
),
Container(
width: 100,
height: 100,
child: Align(
alignment: Alignment.center,
child: Text('Update Profile'.toUpperCase()),
),
),
],
),
),
),
// TextButton (
// onPressed: (){
// //just logout, implement pop dialog later
// // FirebaseAuth.instance.signOut();
// // Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_)=> loginPage()));
// // currentUser = null;
// // setState(() {
// // });
// // still showing error... try to fix asap
// FirebaseAuth.instance.signOut().then((_){
// userIsLoggedIn = false;
// Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> loginPage()));
// //currentUser = null;
// setState(() {
//
// });
// });
// },
// child: Text('SignOut'))
],
)
);
}
}
User.dart for user Model
import 'package:bedc_app/utils/constants.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class User{
String username;
String email;
String userId;
String accountNum;
bool isAdmin;
String profileImage;
String profileImageThumb;
User({
this.username,
this.email,
this.userId,
this.accountNum,
this.isAdmin,
this.profileImage,
this.profileImageThumb
});
factory User.fromSnapshot(DocumentSnapshot doc){
return User(
username: doc.data[Constants.USERNAME],
email: doc.data[Constants.EMAIL],
userId: doc.data[Constants.USER_ID],
accountNum: doc.data[Constants.ACCOUNT_NUM],
isAdmin: doc.data[Constants.IS_ADMIN],
profileImage: doc.data[Constants.PROFILE_IMAGE],
profileImageThumb: doc.data[Constants.PROFILE_IMAGE_THUMB]
);
}
}
Having signed the user up, im getting error The getter 'data' was called on null. Receiver: null Tried calling: data.
i dont know which part of the code is causing this exception

This error generally show when you try to get some attribute on null object.
In your case, call one of doc.data[..] in file User.dart generate the error that means doc == null is true.
Verify that widget.userDoc is not null at this line currentUser = User.fromSnapshot(widget.userDoc); on initState method of Home_page.dart file
So error provide in one of HomePage call who require a non null userDoc (todo: make sure your data is not null using assert and add #required before required variable on your class exp: HomePage({#required this.userDoc,}): assert(userDoc != null, "BOooh my userDoc may be not null"); that help very much when you debug your app)
finaly your problem provide in signUpUserWithFirebase() method of your Signup_page.dart file... here Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => HomePage()));
Try to replace by this getUserData(result.user.uid) so your methode should become
signUpUserWithFirebase(){
FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email,
password: password
).then((AuthResult result){
//Authresult cant be stored to string.....
storeUserDataToFirestore(result.user.uid);
if(result.user.uid != null){
getUserData(result.user.uid); // replaced line
}
}).catchError((e){
print(e);
isLoading = false;
setState(() { });
});
}

Related

Dont understand why I am getting this error in flutter using image_picker

The only error I get here is for the code File selectedImage; and the error states "Non-nullable instance field 'selectedImage' must be initialized. Try adding an initializer expression, or a generative constructor that initializes it, or mark it 'late'.
Here is my code:
import 'dart:io';
import 'package:tennis_event_app/services/crud.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:random_string/random_string.dart';
class CreateBlog extends StatefulWidget {
#override
_CreateBlogState createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
//
File selectedImage;
final picker = ImagePicker();
bool isLoading = false;
CrudMethods crudMethods = new CrudMethods();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
selectedImage = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
Future<void> uploadBlog() async {
if (selectedImage != null) {
// upload the image
setState(() {
isLoading = true;
});
Reference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("blogImages")
.child("${randomAlphaNumeric(9)}.jpg");
final UploadTask task = firebaseStorageRef.putFile(selectedImage);
var imageUrl;
await task.whenComplete(() async {
try {
imageUrl = await firebaseStorageRef.getDownloadURL();
} catch (onError) {
print("Error");
}
print(imageUrl);
});
// print(downloadUrl);
Map<String, dynamic> blogData = {
"imgUrl": imageUrl,
"author": authorTextEditingController.text,
"title": titleTextEditingController.text,
"desc": descTextEditingController.text
};
crudMethods.addData(blogData).then((value) {
setState(() {
isLoading = false;
});
Navigator.pop(context);
});
// upload the blog info
}
}
//
TextEditingController titleTextEditingController =
new TextEditingController();
TextEditingController descTextEditingController = new TextEditingController();
TextEditingController authorTextEditingController =
new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Create Blog"),
actions: [
GestureDetector(
onTap: () {
uploadBlog();
},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.file_upload)),
)
],
),
body: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(),
))
: SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(8)),
child: Image.file(
selectedImage,
fit: BoxFit.cover,
),
),
)
: Container(
height: 150,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius:
BorderRadius.all(Radius.circular(8))),
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: Icon(
Icons.camera_alt,
color: Colors.white,
),
),
),
TextField(
controller: titleTextEditingController,
decoration: InputDecoration(hintText: "enter title"),
),
TextField(
controller: descTextEditingController,
decoration: InputDecoration(hintText: "enter desc"),
),
TextField(
controller: authorTextEditingController,
decoration:
InputDecoration(hintText: "enter author name"),
),
],
)),
),
);
}
}
I also get two warnings, but not sure if there is really a problem here. this is the warning for lines 37 and 118, "The operand can't be null, so the condition is always true."
Any help would be greatly appreciated, I have been stuck on this for two days!
It seems you're using null safety. So the problem is File selectedImage is marked as being not nullable, but you're not initializing it in the constructor. Try replacing it with File? selectedImage or late File selectedImage.
At lines 37 and 118 remove the ! as it is not necessary.
I suggest you to read https://flutter.dev/docs/null-safety as it is explained in great details.

A non-null String must be provided to a Text widget flutter

I have this problem with this code. I tried to solve the problem, but I did not succeed. Please Help
Please see the screenshots to understand the problem well
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 370 pos 10: 'data != null'
Pictures description error
null in firebase
The users email address.Will be null if signing in anonymously.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flash_chat/constants.dart';
class ChatScreen extends StatefulWidget {
static const Id = 'chat_screen';
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
// ignore: deprecated_member_use
final _firestore = Firestore.instance;
final _auth = FirebaseAuth.instance;
// ignore: deprecated_member_use
FirebaseUser loggedInUser;
String messageText;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
// ignore: await_only_futures
final user = await _auth.currentUser;
if (user != null) {
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e) {
print(e);
}
}
// void getMessages() async {
// // ignore: deprecated_member_use
// final messages = await _firestore.collection('Messages').getDocuments();
// // ignore: deprecated_member_use
// for (var message in messages.docs) {
// print(message.data());
// }
// }
void messagesStream() async {
await for (var snapshot in _firestore.collection('Messages').snapshots()) {
for (var message in snapshot.docs) {
print(message.data());
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
messagesStream();
//_auth.signOut();
//Navigator.pop(context);
}),
],
title: Text('⚡️Chat'),
backgroundColor: Colors.lightBlueAccent,
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('Messages').snapshots(),
// ignore: missing_return
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightBlueAccent,
));
}
// ignore: deprecated_member_use
final messages = snapshot.data.documents;
List<Messagebubble> messagebubbles = [];
for (var message in messages) {
final messageText = message.data()['text'];
final messagesendar = message.data()['Sender'];
final messagebubble = Messagebubble(
sendar: messagesendar,
text: messageText,
);
messagebubbles.add(messagebubble);
}
return Expanded(
child: ListView(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 20.0,
),
children: messagebubbles,
),
);
},
),
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (value) {
messageText = value;
},
decoration: kMessageTextFieldDecoration,
),
),
FlatButton(
onPressed: () {
_firestore.collection('Messages').add({
'text': messageText,
'Sender': loggedInUser,
});
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
);
}
}
class Messagebubble extends StatelessWidget {
Messagebubble({
Key key,
this.sendar,
this.text,
}) : super(key: key);
final String sendar;
final String text;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Column(
children: [
Text(
sendar,
style: TextStyle(
fontSize: 12.0,
color: Colors.black54,
),
),
Material(
borderRadius: BorderRadius.circular(30.0),
elevation: 5.0,
color: Colors.lightBlueAccent,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
child: Text(
text,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
),
),
],
),
);
}
}
You just need to check whether the text that you are passing is null or not. If it is null, you can show that the user is Anonymous.
final messageText = message.data()['text'];
final messagesendar = message.data()['Sender'] ?? 'Anonymous'; // If null then use 'Anonymous'
final messagebubble = Messagebubble(
sendar: messagesendar,
text: messageText,
);
Flutter doesn't allow you to pass null to Text widgets.

Different content for different user Flutter

I've been building an app where users can make a reservation for cat grooming. I already connected the app to Firebase where users can register and log in to the app. Here is the problem, every time I log in with different user account, the reservation history from the other users still there.
How can I make different content for different users that login? so each user can have their own content.
Here is the code from history page.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class HistoryPage extends StatefulWidget {
static const String id = 'HistoryPage';
#override
_HistoryPageState createState() => _HistoryPageState();
}
class _HistoryPageState extends State<HistoryPage> {
final _firestore = Firestore.instance;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 70.0, 25.0),
child: Text(
'History',
style: TextStyle(fontSize: 35.0),
),
),
Column(
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('ReservationData').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
final messages = snapshot.data.documents;
List<HistoryBox> historyWidgets = [];
for (var message in messages) {
final historyDate = message.data['Reservation Date'];
final historyTime = message.data['Reservation Time'];
final historyWidget =
HistoryBox(date: historyDate, time: historyTime);
historyWidgets.add(historyWidget);
}
return Column(
children: historyWidgets,
);
},
),
],
)
],
)),
);
}
}
class HistoryBox extends StatelessWidget {
final String date;
final String time;
HistoryBox({this.date, this.time});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Material(
elevation: 5.0,
child: Container(
child: Text(
'Date Reservation : \n $date and $time',
style: TextStyle(
fontSize: 20.0,
),
),
),
),
);
}
}
(Updated)
This is the code for users to sign up.
import 'package:flutter/material.dart';
import 'package:project_pi/screens/HomePage/home_page.dart';
import 'inputform_signup.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class SignUpPage extends StatefulWidget {
static const String id = 'SignUpPage';
#override
_SignUpPageState createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
final _firestore = Firestore.instance;
final _auth = FirebaseAuth.instance;
bool showSpinner = false;
String nama;
String email;
String password;
String phoneNumber;
#override
Widget build(BuildContext context) {
return Scaffold(
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Form(
child: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'SIGN UP',
style: TextStyle(
fontSize: 28.0,
),
),
InputForm(
hint: 'Full Name',
hidetext: false,
onChanged: (value) {
nama = value;
},
),
InputForm(
hint: 'Email Address',
hidetext: false,
onChanged: (value) {
email = value;
},
),
InputForm(
hint: 'Phone Number',
hidetext: false,
onChanged: (value) {
phoneNumber = value;
},
),
InputForm(
hint: 'Password',
hidetext: true,
onChanged: (value) {
password = value;
},
),
InputForm(
hint: 'Confirm Password',
hidetext: true,
),
SizedBox(height: 15.0),
Container(
height: 45.0,
width: 270.0,
child: RaisedButton(
child: Text('SIGN UP'),
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
_firestore.collection('UserAccount').add({
'Email Address': email,
'Full Name': nama,
'Phone Number': phoneNumber,
});
if (newUser != null) {
Navigator.pushNamed(context, HomePage.id);
}
setState(() {
showSpinner = false;
});
} catch (e) {
print(e);
}
},
),
),
SizedBox(
height: 15.0,
),
Text('Have an Account?'),
SizedBox(
height: 7.5,
),
InkWell(
child: Text(
'SIGN IN',
style: TextStyle(
color: Colors.red,
),
),
onTap: () {
AlertDialog(
title: Text("Finish?"),
content: Text("Are you sure with the data?"),
actions: <Widget>[
FlatButton(onPressed: null, child: null)
],
);
},
),
],
),
),
),
),
),
),
);
}
}
And this is the class for the current user that logged in
import 'package:flutter/material.dart';
import 'package:project_pi/screens/HomePage/homebutton.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:project_pi/screens/LiveMaps/live_maps.dart';
import 'package:project_pi/screens/LoginPage/HalamanLogin.dart';
import 'package:project_pi/screens/ReservationHistory/history_page.dart';
import 'package:project_pi/screens/ReservationPage/information_detail.dart';
class HomePage extends StatefulWidget {
static const String id = "HomePage";
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Expanded(
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 256.0, 47.0),
child: Text(
'Home',
style: TextStyle(fontSize: 35.0),
),
),
Center(
child: Column(
children: <Widget>[
HomeNavButton(
prefixIcon: Icons.date_range,
textbutton: 'Make Reservation',
onPressed: () {
Navigator.pushNamed(context, InformationDetail.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.list,
textbutton: 'Reservation History',
onPressed: () {
Navigator.pushNamed(context, HistoryPage.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.gps_fixed,
textbutton: 'Live Maps Track',
onPressed: () {
Navigator.pushNamed(context, LiveMaps.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.person,
textbutton: 'Account Profile',
onPressed: () {
FirebaseAuth.instance.signOut();
Navigator.pushNamed(context, HalamanLogin.id);
},
),
],
),
),
],
),
),
),
),
);
}
}
how to implement the filter for each current user that logged in so it can show the content based on users?
when user creates an account via firebase they get assigned a uid userId which can be obtained by
String userId;
getCurrentUser() async {
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
setState(() {
userId = firebaseUser.uid;
});
}
and then while saving reservations you can include a field "userId":userid
now when you query you can query for your currentUser
_firestore.collection('ReservationData') .where("userId", isEqualTo: userId).snapshots(),

Sign In two different types of users

I am developing an App for home tuition using Flutter and Firebase, but I am having a problem in my SignIn screen as I want to send teacher and student to different profile screens but I can't make a good logic for it. I tried assigning a string that will be compared to send each User to respective screens but it did not work as it provides me with either null. Here is a code of my SignIn Screen.
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:etutor/Animation/FadeAnimation.dart';
import 'package:etutor/ReusableMaterial/BackArrow.dart';
import 'package:etutor/ReusableMaterial/Constants.dart';
import 'package:etutor/ReusableMaterial/Loading.dart';
import 'package:etutor/ReusableMaterial/ReusableButton.dart';
import 'package:etutor/ReusableMaterial/ReusableCard.dart';
import 'package:etutor/Screens/Index.dart';
import 'package:etutor/Screens/ProfileSelection.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class SignIn extends StatefulWidget {
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final Firestore _firestore = Firestore.instance;
String email;
String password;
bool pass1 = true;
String userType;
String loggedInUserID;
bool loading = false;
void showErrorMessage(String title, String description) {
AwesomeDialog(
context: context,
dialogType: DialogType.ERROR,
animType: AnimType.BOTTOMSLIDE,
tittle: title,
desc: description,
).show();
}
Future getUserType() async {
userType = (await _firestore
.collection('userData')
.document(loggedInUserID)
.get()) as String;
print(userType);
}
#override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: kBackgroundColor,
body: SafeArea(
child: ListView(
children: <Widget>[
SizedBox(height: 35),
FadeAnimation(
0.5,
Center(
child: Text(
'Sign In',
style: kHeadingStyle,
),
),
),
BackArrow(),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FadeAnimation(
0.5,
Text(
'Enter your details to access your Account.',
style: kTextLineStyle,
),
),
],
),
SizedBox(height: 45),
Padding(
padding: const EdgeInsets.only(left: 30, right: 30),
child: FadeAnimation(
0.5,
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Color.fromRGBO(84, 104, 255, .3),
blurRadius: 20,
offset: Offset(0, 10),
)
]),
child: Column(
children: <Widget>[
ReusableCard(
onChanged: (value) {
email = value;
},
hintLabel: 'Email',
),
ReusablePasswordCard(
onChanged: (value) {
password = value;
},
hintLabel: 'Password',
pass: pass1,
onPress: () {
setState(() {
pass1 = !pass1;
});
},
),
],
),
),
),
),
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 28),
),
FadeAnimation(
0.5,
FlatButton(
child: Text(
'Forgot Password ?',
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 15,
color: kBlueColor,
),
),
onPressed: () {},
),
),
],
),
SizedBox(
height: 30,
),
FadeAnimation(
0.5,
Center(
child: Text(
'Don\'t have an Account ?',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xFF546270),
),
),
),
),
FadeAnimation(
0.5,
Center(
child: FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfileSelection(),
),
);
},
child: Text(
'SIGN UP',
style: TextStyle(
color: kBlueColor,
),
),
),
),
),
SizedBox(
height: 15,
),
FadeAnimation(
0.5,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ReusableButton(
label: 'Continue',
onPress: () async {
if (!email.contains('#') ||
email == null ||
!email.contains('.com')) {
showErrorMessage('Invalid Email',
'The email you entered is wrong, please check your email format and try again');
} else if (password == null) {
showErrorMessage('Invalid Password',
'The password field is empty');
} else {
try {
setState(() {
loading = true;
});
FirebaseUser signedInUser =
(await _auth.signInWithEmailAndPassword(
email: email, password: password))
.user;
if (!signedInUser.isEmailVerified) {
setState(() {
loading = false;
});
AwesomeDialog(
context: context,
dialogType: DialogType.ERROR,
animType: AnimType.BOTTOMSLIDE,
tittle: 'Error!',
desc:
'Your email has not been verified please verify your email first')
.show();
} else {
if (signedInUser != null) {
setState(() {
loggedInUserID = signedInUser.uid;
// print(loggedInUserID);
});
}
while (loggedInUserID == null) {}
if (loggedInUserID != null) {
getUserType();
setState(() {
loading = false;
});
print(loggedInUserID);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Index(loggedInUserID),
),
);
}
}
} catch (e) {
print(e);
showErrorMessage('Error', e);
}
}
},
),
],
),
),
],
),
),
);
}
}
It returns null because your getUserType() function is async and when you check the user type it doesn't wait for your function to complete and return the data.
You must wait for data to be retrieved on way doing it is by using await
if (loggedInUserID != null) {
await getUserType();
setState(() {
loading = false;
});

Flutter: Firebase Auth endless loop

I want to build a Flutter login screen working with Firebase Auth. I posted the Code below. When i run the App, the _switchToHomePage() method is called endless. So the app keeps opening an new HomeScreen until I close the app.
Thanks for help!
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'home_page.dart';
import 'register.dart';
import 'error_dialog.dart';
class LoginForm extends StatefulWidget {
#override
State<StatefulWidget> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
bool _hidePassword = true;
void _checkUserIsLoggedIn() {
_firebaseAuth.currentUser().then((firebaseUser) {
if (firebaseUser == null) {
print('no user logged in');
} else {
print('User logged in');
_switchToHomePage();
}
});
}
void _switchToHomePage() {
print('switching to home page...');
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
this.deactivate();
}
void _login() {
String email = emailController.text;
String password = passwordController.text;
_firebaseAuth
.signInWithEmailAndPassword(email: email, password: password)
.then((firebaseUser) {
if (firebaseUser != null) {
print('Login succesfull');
_switchToHomePage();
} else {
throw Exception('FirebaseUser is null');
}
}).catchError((exception) {
//TODO make better error messages
print(exception.message);
ErrorDialog(
context: this.context,
title: 'Error',
message: exception.message);
});
}
void _showRegisterScreen() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => RegisterForm()));
}
#override
Widget build(BuildContext context) {
_checkUserIsLoggedIn();
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: ListView(
padding: EdgeInsets.fromLTRB(15, 30, 15, 0),
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 60)),
Text(
'placeholder',
style: TextStyle(
color: Colors.teal,
fontSize: 40,
),
),
Padding(padding: EdgeInsets.only(top: 60)),
Padding(padding: EdgeInsets.only(top: 40)),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
prefixIcon: Icon(Icons.email),
labelText: 'E-Mailadresse',
border: UnderlineInputBorder()),
),
Padding(padding: EdgeInsets.only(top: 20)),
TextField(
controller: passwordController,
obscureText: _hidePassword,
decoration: InputDecoration(
labelText: 'Passwort',
border: UnderlineInputBorder(),
prefixIcon: Icon(Icons.security),
suffixIcon: IconButton(
icon: Icon(Icons.remove_red_eye),
color: _hidePassword
? Theme.of(context).primaryColor
: Colors.grey,
onPressed: () => this.setState(() {
_hidePassword = !_hidePassword;
}),
)),
),
Padding(padding: EdgeInsets.only(top: 5)),
Container(
child: FlatButton(
onPressed: () => print('Forgot password'),
child: Text(
'Passwort vergessen?',
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
width: double.infinity,
alignment: Alignment.centerRight,
),
Padding(padding: EdgeInsets.only(top: 40)),
RaisedButton(
onPressed: _login,
color: Theme.of(context).primaryColor,
child: Text(
'Login',
style: TextStyle(color: Colors.white),
),
),
Padding(padding: EdgeInsets.only(top: 20)),
FlatButton(
onPressed: _showRegisterScreen,
child: Text(
'Neuen Account erstellen',
style: TextStyle(
fontSize: 16,
color: Theme.of(context).accentColor,
),
),
)
],
));
}
}
The reason you get that, is because _checkUserIsLoggedIn(); which contains navigation to the HomePage is the first method inside build method. Inside the build() method you have setState() on the TextField, therefore everytime the state is changing then the build() method is getting called and _checkUserIsLoggedIn() is also getting called. To solve that try the following:
#override
initState() {
super.initState();
_firebaseAuth.currentUser().then((firebaseUser) {
if (firebaseUser == null) {
print('no user logged in');
} else {
print('User logged in');
_switchToHomePage();
}
});
}
Inside the lifecycle method initState() check if the user is logged in and navigate to the HomePage. Also remove the method _checkUserIsLoggedIn(); from the build method
I just solved it. I replaced:
Navigator.push(
context, MaterialPageRoute(builder: (context) => RegisterForm()));
with
Navigator.pushAndRemoveUntil(
context, MaterialPageRoute(builder: (context) => HomePage()), (e) => false);

Resources