how to add CircularProgressIndicator using provider with firebase - firebase

i went through google code lab of flutter firebase using provider package every thing working fine as mentioned in codelab i like the way they design Authentication widget passing functions from it, in below code i want to add CircularProgressIndicator on waiting state, i don't understand where do i add condition of isLoading is equals to true then wait otherwise dosomething with functions passed by Authentication widget.
main.dart
import 'package:firebase_core/firebase_core.dart'; // new
import 'package:firebase_auth/firebase_auth.dart'; // new
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart'; // new
import 'src/authentication.dart'; // new
import 'src/widgets.dart';
void main() {
// Modify from here
runApp(
ChangeNotifierProvider(
create: (context) => ApplicationState(),
builder: (context, _) => App(),
),
);
// to here.
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Meetup',
theme: ThemeData(
buttonTheme: Theme.of(context).buttonTheme.copyWith(
highlightColor: Colors.deepPurple,
),
primarySwatch: Colors.deepPurple,
textTheme: GoogleFonts.robotoTextTheme(
Theme.of(context).textTheme,
),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Firebase Meetup'),
),
body: ListView(
children: <Widget>[
Image.asset('assets/codelab.png'),
SizedBox(height: 8),
IconAndDetail(Icons.calendar_today, 'October 30'),
IconAndDetail(Icons.location_city, 'San Francisco'),
// Add from here
Consumer<ApplicationState>(
builder: (context, appState, _) => Authentication(
email: appState.email,
loginState: appState.loginState,
startLoginFlow: appState.startLoginFlow,
verifyEmail: appState.verifyEmail,
signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
cancelRegistration: appState.cancelRegistration,
registerAccount: appState.registerAccount,
signOut: appState.signOut,
),
),
// to here
Divider(
height: 8,
thickness: 1,
indent: 8,
endIndent: 8,
color: Colors.grey,
),
Header("What we'll be doing"),
Paragraph(
'Join us for a day full of Firebase Workshops and Pizza!',
),
],
),
);
}
}
class ApplicationState extends ChangeNotifier {
ApplicationState() {
init();
}
Future<void> init() async {
await Firebase.initializeApp();
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
_loginState = ApplicationLoginState.loggedIn;
} else {
_loginState = ApplicationLoginState.loggedOut;
}
notifyListeners();
});
}
ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
ApplicationLoginState get loginState => _loginState;
String? _email;
String? get email => _email;
void startLoginFlow() {
_loginState = ApplicationLoginState.emailAddress;
notifyListeners();
}
void verifyEmail(
String email,
void Function(FirebaseAuthException e) errorCallback,
) async {
try {
var methods = await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);
if (methods.contains('password')) {
_loginState = ApplicationLoginState.password;
} else {
_loginState = ApplicationLoginState.register;
}
_email = email;
notifyListeners();
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
void signInWithEmailAndPassword(
String email,
String password,
void Function(FirebaseAuthException e) errorCallback,
) async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
void cancelRegistration() {
_loginState = ApplicationLoginState.emailAddress;
notifyListeners();
}
void registerAccount(String email, String displayName, String password,
void Function(FirebaseAuthException e) errorCallback) async {
try {
var credential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
await credential.user!.updateProfile(displayName: displayName);
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
void signOut() {
FirebaseAuth.instance.signOut();
/// here is not notifylistener();
}
}
authentication.dart
import 'package:flutter/material.dart';
import 'widgets.dart';
enum ApplicationLoginState {
loggedOut,
emailAddress,
register,
password,
loggedIn,
}
class Authentication extends StatelessWidget {
const Authentication({
required this.loginState,
required this.email,
required this.startLoginFlow,
required this.verifyEmail,
required this.signInWithEmailAndPassword,
required this.cancelRegistration,
required this.registerAccount,
required this.signOut,
});
final ApplicationLoginState loginState;
final String? email;
final void Function() startLoginFlow;
final void Function(
String email,
void Function(Exception e) error,
) verifyEmail;
final void Function(
String email,
String password,
void Function(Exception e) error,
) signInWithEmailAndPassword;
final void Function() cancelRegistration;
final void Function(
String email,
String displayName,
String password,
void Function(Exception e) error,
) registerAccount;
final void Function() signOut;
#override
Widget build(BuildContext context) {
switch (loginState) {
case ApplicationLoginState.loggedOut:
return Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 24, bottom: 8),
child: StyledButton(
onPressed: () {
startLoginFlow();
},
child: const Text('RSVP'),
),
),
],
);
case ApplicationLoginState.emailAddress:
return EmailForm(
callback: (email) =>
verifyEmail(email, (e) => _showErrorDialog(context, 'Invalid email', e)));
case ApplicationLoginState.password:
return PasswordForm(
email: email!,
login: (email, password) {
print("CONTEXT $context");
signInWithEmailAndPassword(
email, password, (e) => _showErrorDialog(context, 'Failed to sign in', e));
},
);
case ApplicationLoginState.register:
return RegisterForm(
email: email!,
cancel: () {
cancelRegistration();
},
registerAccount: (
email,
displayName,
password,
) {
registerAccount(email, displayName, password,
(e) => _showErrorDialog(context, 'Failed to create account', e));
},
);
case ApplicationLoginState.loggedIn:
return Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 24, bottom: 8),
child: StyledButton(
onPressed: () {
signOut();
},
child: const Text('LOGOUT'),
),
),
],
);
default:
return Row(
children: const [
Text("Internal error, this shouldn't happen..."),
],
);
}
}
void _showErrorDialog(BuildContext context, String title, Exception e) {
print("CONTEXT $context");
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
title: Text(
title,
style: const TextStyle(fontSize: 24),
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'${(e as dynamic).message}',
style: const TextStyle(fontSize: 18),
),
],
),
),
actions: <Widget>[
StyledButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'OK',
style: TextStyle(color: Colors.deepPurple),
),
),
],
);
},
);
}
}
class EmailForm extends StatefulWidget {
const EmailForm({required this.callback});
final void Function(String email) callback;
#override
_EmailFormState createState() => _EmailFormState();
}
class _EmailFormState extends State<EmailForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_EmailFormState');
final _controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Sign in with email'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 30),
child: StyledButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
widget.callback(_controller.text);
}
},
child: const Text('NEXT'),
),
),
],
),
],
),
),
),
],
);
}
}
class RegisterForm extends StatefulWidget {
const RegisterForm({
required this.registerAccount,
required this.cancel,
required this.email,
});
final String email;
final void Function(String email, String displayName, String password) registerAccount;
final void Function() cancel;
#override
_RegisterFormState createState() => _RegisterFormState();
}
class _RegisterFormState extends State<RegisterForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_RegisterFormState');
final _emailController = TextEditingController();
final _displayNameController = TextEditingController();
final _passwordController = TextEditingController();
#override
void initState() {
super.initState();
_emailController.text = widget.email;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Create account'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _emailController,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _displayNameController,
decoration: const InputDecoration(
hintText: 'First & last name',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your account name';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
hintText: 'Password',
),
obscureText: true,
validator: (value) {
if (value!.isEmpty) {
return 'Enter your password';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: widget.cancel,
child: const Text('CANCEL'),
),
const SizedBox(width: 16),
StyledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.registerAccount(
_emailController.text,
_displayNameController.text,
_passwordController.text,
);
}
},
child: const Text('SAVE'),
),
const SizedBox(width: 30),
],
),
),
],
),
),
),
],
);
}
}
class PasswordForm extends StatefulWidget {
const PasswordForm({
required this.login,
required this.email,
});
final String email;
final void Function(String email, String password) login;
#override
_PasswordFormState createState() => _PasswordFormState();
}
class _PasswordFormState extends State<PasswordForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_PasswordFormState');
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
#override
void initState() {
super.initState();
_emailController.text = widget.email;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Sign in'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _emailController,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
hintText: 'Password',
),
obscureText: true,
validator: (value) {
if (value!.isEmpty) {
return 'Enter your password';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(width: 16),
StyledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.login(
_emailController.text,
_passwordController.text,
);
}
},
child: const Text('SIGN IN'),
),
const SizedBox(width: 30),
],
),
),
],
),
),
),
],
);
}
}
widgets.dart
import 'package:flutter/material.dart';
class Header extends StatelessWidget {
const Header(this.heading);
final String heading;
#override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
heading,
style: const TextStyle(fontSize: 24),
),
);
}
class Paragraph extends StatelessWidget {
const Paragraph(this.content);
final String content;
#override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Text(
content,
style: const TextStyle(fontSize: 18),
),
);
}
class IconAndDetail extends StatelessWidget {
const IconAndDetail(this.icon, this.detail);
final IconData icon;
final String detail;
#override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(icon),
const SizedBox(width: 8),
Text(
detail,
style: const TextStyle(fontSize: 18),
)
],
),
);
}
class StyledButton extends StatelessWidget {
const StyledButton({required this.child, required this.onPressed});
final Widget child;
final void Function() onPressed;
#override
Widget build(BuildContext context) => OutlinedButton(
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.deepPurple)),
onPressed: onPressed,
child: child,
);
}
pubspec.yaml (version numbers at time of posting)
cloud_firestore: ^1.0.0 # new
firebase_auth: ^1.0.0 # new
google_fonts: ^2.0.0
provider: ^5.0.0

I answer my question, you could do this by adding bool isLoading variable in ApplicationState class and set its value on conditioned base from any method(signInWithEmailAndPassword) present in ApplicationState and pass isLoading to Authentication widget and check condition in build method e.g if isLoading true then show CircularProgressIndicator check below code for more details:
main.dart
import 'package:firebase_core/firebase_core.dart'; // new
import 'package:firebase_auth/firebase_auth.dart'; // new
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart'; // new
import 'src/authentication.dart'; // new
import 'src/widgets.dart';
void main() {
// Modify from here
runApp(
ChangeNotifierProvider(
create: (context) => ApplicationState(),
builder: (context, _) => App(),
),
);
// to here.
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Meetup',
theme: ThemeData(
buttonTheme: Theme.of(context).buttonTheme.copyWith(
highlightColor: Colors.deepPurple,
),
primarySwatch: Colors.deepPurple,
textTheme: GoogleFonts.robotoTextTheme(
Theme.of(context).textTheme,
),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Firebase Meetup'),
),
body: ListView(
children: <Widget>[
Image.asset('assets/codelab.png'),
SizedBox(height: 8),
IconAndDetail(Icons.calendar_today, 'October 30'),
IconAndDetail(Icons.location_city, 'San Francisco'),
// Add from here
Consumer<ApplicationState>(
builder: (context, appState, _) => Authentication(
isLoading: appState.isLoading,
email: appState.email,
loginState: appState.loginState,
startLoginFlow: appState.startLoginFlow,
verifyEmail: appState.verifyEmail,
signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
cancelRegistration: appState.cancelRegistration,
registerAccount: appState.registerAccount,
signOut: appState.signOut,
),
),
// to here
Divider(
height: 8,
thickness: 1,
indent: 8,
endIndent: 8,
color: Colors.grey,
),
Header("What we'll be doing"),
Paragraph(
'Join us for a day full of Firebase Workshops and Pizza!',
),
],
),
);
}
}
class ApplicationState extends ChangeNotifier {
ApplicationState() {
init();
}
Future<void> init() async {
await Firebase.initializeApp();
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
_loginState = ApplicationLoginState.loggedIn;
} else {
_loginState = ApplicationLoginState.loggedOut;
}
notifyListeners();
});
}
ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
ApplicationLoginState get loginState => _loginState;
bool get isLoading => _isLoading;
String? _email;
String? get email => _email;
bool _isLoading = false;
void startLoginFlow() {
_loginState = ApplicationLoginState.emailAddress;
notifyListeners();
}
void verifyEmail(
String email,
void Function(FirebaseAuthException e) errorCallback,
) async {
try {
var methods = await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);
if (methods.contains('password')) {
_loginState = ApplicationLoginState.password;
} else {
_loginState = ApplicationLoginState.register;
}
_email = email;
notifyListeners();
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
void signInWithEmailAndPassword(
String email,
String password,
void Function(FirebaseAuthException e) errorCallback,
) async {
try {
if (!this.isLoading) {
this._isLoading = true;
notifyListeners();
}
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
} on FirebaseAuthException catch (e) {
errorCallback(e);
this._isLoading = false;
notifyListeners();
}
}
void cancelRegistration() {
_loginState = ApplicationLoginState.emailAddress;
notifyListeners();
}
void registerAccount(String email, String displayName, String password,
void Function(FirebaseAuthException e) errorCallback) async {
try {
var credential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
await credential.user!.updateProfile(displayName: displayName);
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
void signOut() {
FirebaseAuth.instance.signOut();
/// here is not notifylistener();
}
}
authentication.dart
import 'package:flutter/material.dart';
import 'widgets.dart';
enum ApplicationLoginState {
loggedOut,
emailAddress,
register,
password,
loggedIn,
}
class Authentication extends StatelessWidget {
const Authentication({
required this.isLoading,
required this.loginState,
required this.email,
required this.startLoginFlow,
required this.verifyEmail,
required this.signInWithEmailAndPassword,
required this.cancelRegistration,
required this.registerAccount,
required this.signOut,
});
final bool isLoading;
final ApplicationLoginState loginState;
final String? email;
final void Function() startLoginFlow;
final void Function(
String email,
void Function(Exception e) error,
) verifyEmail;
final void Function(
String email,
String password,
void Function(Exception e) error,
) signInWithEmailAndPassword;
final void Function() cancelRegistration;
final void Function(
String email,
String displayName,
String password,
void Function(Exception e) error,
) registerAccount;
final void Function() signOut;
#override
Widget build(BuildContext context) {
if (this.isLoading) {
return Stack(
children: [Center(child: CircularProgressIndicator(value: null))],
);
}
switch (loginState) {
case ApplicationLoginState.loggedOut:
return Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 24, bottom: 8),
child: StyledButton(
onPressed: () {
startLoginFlow();
},
child: const Text('RSVP'),
),
),
],
);
case ApplicationLoginState.emailAddress:
return EmailForm(
callback: (email) =>
verifyEmail(email, (e) => _showErrorDialog(context, 'Invalid email', e)));
case ApplicationLoginState.password:
return PasswordForm(
email: email!,
login: (email, password) {
print("CONTEXT $context");
signInWithEmailAndPassword(
email, password, (e) => _showErrorDialog(context, 'Failed to sign in', e));
},
);
case ApplicationLoginState.register:
return RegisterForm(
email: email!,
cancel: () {
cancelRegistration();
},
registerAccount: (
email,
displayName,
password,
) {
registerAccount(email, displayName, password,
(e) => _showErrorDialog(context, 'Failed to create account', e));
},
);
case ApplicationLoginState.loggedIn:
return Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 24, bottom: 8),
child: StyledButton(
onPressed: () {
signOut();
},
child: const Text('LOGOUT'),
),
),
],
);
default:
return Row(
children: const [
Text("Internal error, this shouldn't happen..."),
],
);
}
}
void _showErrorDialog(BuildContext context, String title, Exception e) {
print("CONTEXT $context");
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
title: Text(
title,
style: const TextStyle(fontSize: 24),
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'${(e as dynamic).message}',
style: const TextStyle(fontSize: 18),
),
],
),
),
actions: <Widget>[
StyledButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'OK',
style: TextStyle(color: Colors.deepPurple),
),
),
],
);
},
);
}
}
class EmailForm extends StatefulWidget {
const EmailForm({required this.callback});
final void Function(String email) callback;
#override
_EmailFormState createState() => _EmailFormState();
}
class _EmailFormState extends State<EmailForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_EmailFormState');
final _controller = TextEditingController();
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Sign in with email'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 30),
child: StyledButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
widget.callback(_controller.text);
}
},
child: const Text('NEXT'),
),
),
],
),
],
),
),
),
],
);
}
}
class RegisterForm extends StatefulWidget {
const RegisterForm({
required this.registerAccount,
required this.cancel,
required this.email,
});
final String email;
final void Function(String email, String displayName, String password) registerAccount;
final void Function() cancel;
#override
_RegisterFormState createState() => _RegisterFormState();
}
class _RegisterFormState extends State<RegisterForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_RegisterFormState');
final _emailController = TextEditingController();
final _displayNameController = TextEditingController();
final _passwordController = TextEditingController();
#override
void initState() {
super.initState();
_emailController.text = widget.email;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Create account'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _emailController,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _displayNameController,
decoration: const InputDecoration(
hintText: 'First & last name',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your account name';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
hintText: 'Password',
),
obscureText: true,
validator: (value) {
if (value!.isEmpty) {
return 'Enter your password';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: widget.cancel,
child: const Text('CANCEL'),
),
const SizedBox(width: 16),
StyledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.registerAccount(
_emailController.text,
_displayNameController.text,
_passwordController.text,
);
}
},
child: const Text('SAVE'),
),
const SizedBox(width: 30),
],
),
),
],
),
),
),
],
);
}
}
class PasswordForm extends StatefulWidget {
const PasswordForm({
required this.login,
required this.email,
});
final String email;
final void Function(String email, String password) login;
#override
_PasswordFormState createState() => _PasswordFormState();
}
class _PasswordFormState extends State<PasswordForm> {
final _formKey = GlobalKey<FormState>(debugLabel: '_PasswordFormState');
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
#override
void initState() {
super.initState();
_emailController.text = widget.email;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
const Header('Sign in'),
Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _emailController,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
validator: (value) {
if (value!.isEmpty) {
return 'Enter your email address to continue';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
hintText: 'Password',
),
obscureText: true,
validator: (value) {
if (value!.isEmpty) {
return 'Enter your password';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(width: 16),
StyledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.login(
_emailController.text,
_passwordController.text,
);
}
},
child: const Text('SIGN IN'),
),
const SizedBox(width: 30),
],
),
),
],
),
),
),
],
);
}
}

Related

Flutter: No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

[core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
Where create call Firebase.initializeApp() ?
what should I change in my code? Is there any way to do it? In case you want to see the code please let me know I will update more.
auth.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:quiz2/model/user.dart';
class AuthService {
FirebaseAuth _auth = FirebaseAuth.instance;
UserFire _userFromFirebase(User user){
return user != null ? UserFire(uid: user.uid):null;
}
Future signInEmailAndPass(String email, String password) async {
try {
UserCredential authResult = await _auth.signInWithEmailAndPassword(
email: email, password: password);
User firebaseUser = authResult.user;
return _userFromFirebase(firebaseUser);
} catch (e) {
print(e.toString());
}
}
Future signUpWithEmailAndPassword(String email, String password) async{
try{
UserCredential authResult = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User firebaseUser = authResult.user;
return _userFromFirebase(firebaseUser);
}catch(e){
print(e.toString());
}
}
Future signOut() async{
try{
return await _auth.signOut();
}catch(e){
print(e.toString());
return null;
}
}
}
signup.dart
import 'package:flutter/material.dart';
import 'package:quiz2/database/auth.dart';
import 'package:quiz2/screens/landing.dart';
import 'package:quiz2/screens/signin.dart';
import 'package:quiz2/widgets/widget.dart';
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _formKey = GlobalKey<FormState>();
String email, password, name;
AuthService authService = new AuthService();
bool _isLoading = false;
signUp() async {
if (_formKey.currentState.validate()) {
setState(() {
_isLoading = true;
});
authService.signUpWithEmailAndPassword(email, password).then((val) {
if (val != null) {
setState(() {
_isLoading = false;
});
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => MyHomePage()));
}
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: appBar(context),
backgroundColor: Colors.transparent,
elevation: 0.0,
brightness: Brightness.light,
),
body: _isLoading
? Container(child: Center(child: CircularProgressIndicator()))
: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Column(
children: [
Spacer(),
TextFormField(
validator: (val) {
return val.isEmpty ? 'Enter Name' : null;
},
decoration: InputDecoration(hintText: 'Name'),
onChanged: (val) {
name = val;
},
),
SizedBox(
height: 6,
),
TextFormField(
validator: (val) {
return val.isEmpty ? 'Enter Email' : null;
},
decoration: InputDecoration(hintText: 'Email'),
onChanged: (val) {
email = val;
},
),
SizedBox(
height: 6,
),
TextFormField(
obscureText: true,
validator: (val) {
return val.isEmpty ? 'Enter password' : null;
},
decoration: InputDecoration(hintText: 'Password'),
onChanged: (val) {
password = val;
},
),
SizedBox(
height: 24,
),
GestureDetector(
onTap: () {
signUp();
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(30)),
alignment: Alignment.center,
width: MediaQuery.of(context).size.width - 48,
child: Text(
"Sign Up",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
SizedBox(
height: 18,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Alredy have an account?",
style: TextStyle(fontSize: 16),
),
GestureDetector(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SignIn()));
},
child: Text(" Sign In",
style: TextStyle(
fontSize: 16,
decoration: TextDecoration.underline)))
],
),
SizedBox(
height: 80,
),
],
)),
),
);
}
}
user.dart
class UserFire{
String uid;
UserFire({this.uid});
}
what should I change in my code? Is there any way to do it? In case you want to see the code please let me know I will update more.
You need initialize your firebase .Do as follows:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
Did you complete all the installation steps?
if you answer is yes :
you must check this link

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.

Send data from Flutter Bluetooth app to Firestore

https://i.stack.imgur.com/9k5MB.png
I am new to flutter and I'm working on social distancing app in flutter. I wanted to push the uuid of bluetooth devices discovered to the firestore can someone please help me in doing this
I can print out the discovered devices in my app and i can get rssi uuid txpower
but as rssi keeps varying and scanning happens continuously the devices get pushed into firestore multiple times
i wanted UUID to be pushed into the firestore only once.
Nearby.dart
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:beacon_broadcast/beacon_broadcast.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'homescreen.dart';
import 'material.dart';
class BlueApp extends StatefulWidget {
#override
_BlueAppState createState() => _BlueAppState();
}
BeaconBroadcast beaconBroadcast = BeaconBroadcast();
BeaconStatus _isTransmissionSupported;
bool _isAdvertising = false;
StreamSubscription<bool> _isAdvertisingSubscription;
final databaseReference=Firestore.instance;
String UUID = "3E4D7TJ9008";
void createRecord(String usid) async {
await databaseReference.collection("users")
.document("1")
.setData({
'uuid':usid
});
print('senddddddddingggggg');
DocumentReference ref = await databaseReference.collection("users")
.add({
'uuid':usid
});
print(ref.documentID);
}
class _BlueAppState extends State<BlueApp> {
static const UUID = '39ED98FF';
static const MAJOR_ID = 1;
static const MINOR_ID = 100;
static const TRANSMISSION_POWER = -59;
static const IDENTIFIER = 'com.example.myDeviceRegion';
static const LAYOUT = BeaconBroadcast.ALTBEACON_LAYOUT;
static const MANUFACTURER_ID = 0x0118;
void initState() {
// TODO: implement initState
super.initState();
FlutterBlue.instance.state.listen((state) {
print("im in the init");
print(state);
if (state == BluetoothState.off) {
print("bluetooth is off");
} else if (state == BluetoothState.on) {
print("bluethooth on");
//print(device.id);
}
print("printing eacon");
});
beaconBroadcast.checkTransmissionSupported().then((isTransmissionSupported) {
setState(() {
_isTransmissionSupported = isTransmissionSupported;
print(_isTransmissionSupported);
});
});
_isAdvertisingSubscription =
beaconBroadcast.getAdvertisingStateChange().listen((isAdvertising) {
setState(() {
_isAdvertising = isAdvertising;
});
});
beaconBroadcast
.setUUID(UUID)
.setMajorId(MAJOR_ID)
.setMinorId(MINOR_ID)
.setTransmissionPower(-59)
.setIdentifier(IDENTIFIER)
.setLayout(LAYOUT)
.setManufacturerId(MANUFACTURER_ID)
.start();
if(_isAdvertising==true){
print('Beacon started Advertising');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
color: Colors.lightBlue,
home: StreamBuilder<BluetoothState>(
stream: FlutterBlue.instance.state,
initialData: BluetoothState.turningOn,
builder: (c, snapshot) {
final state = snapshot.data;
print(state);
if (state == BluetoothState.on) {
print("BlueTooth is on");
return FindDevicesScreen();
}
print("BlueTooth is off");
return BluetoothOffScreen(state: state);
}),
);
}
}
class BluetoothOffScreen extends StatelessWidget {
const BluetoothOffScreen({Key key, this.state}) : super(key: key);
final BluetoothState state;
#override
Widget build(BuildContext context) {
_BlueAppState a=new _BlueAppState();
createRecord(UUID);
return Scaffold(
backgroundColor: Colors.lightBlue,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.bluetooth_disabled,
size: 200.0,
color: Colors.white54,
),
Text(
'Bluetooth Adapter is ${state != null ? state.toString().substring(15) : 'not available'}.',
style: Theme.of(context)
.primaryTextTheme
.subhead
.copyWith(color: Colors.white),
),
],
),
),
);
}
}
class FindDevicesScreen extends StatefulWidget {
#override
_FindDevicesScreenState createState() => _FindDevicesScreenState();
}
class _FindDevicesScreenState extends State<FindDevicesScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
FlutterBlue.instance.startScan();
beaconBroadcast.checkTransmissionSupported().then((isTransmissionSupported) {
setState(() {
_isTransmissionSupported = isTransmissionSupported;
print(_isTransmissionSupported);
});
});
_isAdvertisingSubscription =
beaconBroadcast.getAdvertisingStateChange().listen((isAdvertising) {
setState(() {
_isAdvertising = isAdvertising;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Find Devices'),
),
body: RefreshIndicator(
onRefresh: () =>
FlutterBlue.instance.startScan(),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
StreamBuilder<List<BluetoothDevice>>(
stream: Stream.periodic(Duration(seconds: 4))
.asyncMap((_) => FlutterBlue.instance.connectedDevices),
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data
.map((d) => ListTile(
title: Text(d.name),
subtitle: Text(d.id.toString()),
trailing: StreamBuilder<BluetoothDeviceState>(
stream: d.state,
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
print('entering if');
if (true) {
print('id----------------------------------------------did');
}
return Text(snapshot.data.toString());
},
),
))
.toList(),
),
),
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data
.map(
(r) => Card(
child: ScanResultTile(
result: r,
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return null;
})),
),
),
)
.toList(),
),
),
],
),
),
),
);
}
}
material.dart
import 'package:flutter_blue/flutter_blue.dart';
import 'nearby.dart';
class ScanResultTile extends StatelessWidget {
const ScanResultTile({Key key, this.result, this.onTap}) : super(key: key);
final ScanResult result;
final VoidCallback onTap;
Widget _buildTitle(BuildContext context) {
if (result.device.name.length > 0) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
result.device.name,
overflow: TextOverflow.ellipsis,
),
Text(
result.device.id.toString(),
style: Theme.of(context).textTheme.caption,
),
// _buildAdvRow(
// context, 'Distance of the device',(result.rssi!=null && result.advertisementData.txPowerLevel!=null)?"${getDistance(result.rssi,result.advertisementData.txPowerLevel)}":"N/A" ),
],
);
} else {
return Text(result.device.id.toString());
}
}
Widget _buildAdvRow(BuildContext context, String title, String value) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title, style: Theme.of(context).textTheme.caption),
SizedBox(
width: 12.0,
),
Expanded(
child: Text(
value,
style: Theme.of(context)
.textTheme
.caption
.apply(color: Colors.black),
softWrap: true,
),
),
],
),
);
}
String getNiceHexArray(List<int> bytes) {
return '[${bytes.map((i) => i.toRadixString(16).padLeft(2, '0')).join(', ')}]'
.toUpperCase();
}
int getDistance(int rssi, int txPower) {
print("rssi");
print(rssi);
return 10 ^ ((txPower - rssi) / (10 * 2)).round();
}
#override
Widget build(BuildContext context) {
print("rssi");
print(result.rssi);
print("Transmit power");
print(result.advertisementData.txPowerLevel);
// print(result.device.name);
print(result);
// if((getDistance(result.rssi,result.advertisementData.txPowerLevel))<=2)
// {
// createRecord(result.advertisementData.serviceUuids.iterator.moveNext().toString());
// }
return ExpansionTile(
title: _buildTitle(context),
leading: Column(
children: <Widget>[
Text("Tap for more...",style: TextStyle(fontSize: 10.0,color: Colors.lightBlueAccent),)
],
),
children: <Widget>[
_buildAdvRow(
context, 'Distance of the device',(result.rssi!=null && result.advertisementData.txPowerLevel!=null)?"${getDistance(result.rssi,result.advertisementData.txPowerLevel)}":"N/A" ),
_buildAdvRow(context, 'Tx Power Level',
'${result.advertisementData.txPowerLevel ?? 'N/A'}'),
_buildAdvRow(
context,
'Service UUIDs',
(result.advertisementData.serviceUuids.isNotEmpty)? result.advertisementData.serviceUuids.join(', ').toUpperCase(): 'N/A'),
],
);
}
}
class ServiceTile extends StatelessWidget {
final BluetoothService service;
final List<CharacteristicTile> characteristicTiles;
const ServiceTile({Key key, this.service, this.characteristicTiles})
: super(key: key);
#override
Widget build(BuildContext context) {
if (characteristicTiles.length > 0) {
return ExpansionTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Service'),
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.body1
.copyWith(color: Theme.of(context).textTheme.caption.color))
],
),
children: characteristicTiles,
);
} else {
return ListTile(
title: Text('Service'),
subtitle:
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}'),
);
}
}
}
class CharacteristicTile extends StatelessWidget {
final BluetoothCharacteristic characteristic;
final List<DescriptorTile> descriptorTiles;
final VoidCallback onReadPressed;
final VoidCallback onWritePressed;
final VoidCallback onNotificationPressed;
const CharacteristicTile(
{Key key,
this.characteristic,
this.descriptorTiles,
this.onReadPressed,
this.onWritePressed,
this.onNotificationPressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder<List<int>>(
stream: characteristic.value,
initialData: characteristic.lastValue,
builder: (c, snapshot) {
final value = snapshot.data;
return ExpansionTile(
title: ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Characteristic'),
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.body1.copyWith(
color: Theme.of(context).textTheme.caption.color))
],
),
subtitle: Text(value.toString()),
contentPadding: EdgeInsets.all(0.0),
),
children: descriptorTiles,
);
},
);
}
}
class DescriptorTile extends StatelessWidget {
final BluetoothDescriptor descriptor;
final VoidCallback onReadPressed;
final VoidCallback onWritePressed;
const DescriptorTile(
{Key key, this.descriptor, this.onReadPressed, this.onWritePressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Descriptor'),
Text('0x${descriptor.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.body1
.copyWith(color: Theme.of(context).textTheme.caption.color))
],
),
subtitle: StreamBuilder<List<int>>(
stream: descriptor.value,
initialData: descriptor.lastValue,
builder: (c, snapshot) => Text(snapshot.data.toString()),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.file_download,
color: Theme.of(context).iconTheme.color.withOpacity(0.5),
),
onPressed: onReadPressed,
),
IconButton(
icon: Icon(
Icons.file_upload,
color: Theme.of(context).iconTheme.color.withOpacity(0.5),
),
onPressed: onWritePressed,
)
],
),
);
}
}
class AdapterStateTile extends StatelessWidget {
const AdapterStateTile({Key key, #required this.state}) : super(key: key);
final BluetoothState state;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.redAccent,
child: ListTile(
title: Text(
'Bluetooth adapter is ${state.toString().substring(15)}',
style: Theme.of(context).primaryTextTheme.subhead,
),
trailing: Icon(
Icons.error,
color: Theme.of(context).primaryTextTheme.subhead.color,
),
),
);
}
}```
To avoid adding it additional times there are two altenatives.
Alternative 1:
Index the uuid field, as this will allow you to query over this field
Before writing query for documents with this uuid
Write only if the response is empty
This alternative has the advantage that no changes need to be done on firestore and minimun changes on the code, however will have the disadvantage that each write attempt will be preceeded by a read and reads are billed.
Alternative 2:
Change the data structucture on Firestore so that the UUID is the document ID
This has the advantage that the writes won't be preceeded by a read therefore its cheaper on firestore costs. However it needs more code edition and will need to change the data stucture.
for the code the main change is on the following method:
void createRecord(String usid) async {
await databaseReference.collection("users")
.document(usid)
.setData({
'uuid':usid
});
print('senddddddddingggggg');
DocumentReference ref = await databaseReference.collection("users")
.document(usid)
.setData({
'uuid':usid
});
print(ref.documentID);
}

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(),

Flutter Login with firebase return ERROR_INVALID_EMAIL

I get ERROR_INVALID_EMAIL when I try to login to firebase but if I replaced _email and _password with the real email and pass from firebase I get Log In FirebaseUser(Instance of 'PlatformUser')
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Login extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return LoginState();
}
}
class LoginState extends State<Login> {
final GlobalKey<FormState> formState = GlobalKey<FormState>();
String _email;
String _password;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Login Page'),
centerTitle: true,
backgroundColor: Colors.deepOrange,
),
body: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Form(
key: formState,
child: Container(
child: Column(
children: <Widget>[
TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
decoration: InputDecoration(
icon: Icon(Icons.email),
hintText: 'Enter Your E-mail',
),
validator: (val) {
if (val.isEmpty) {
return 'Please Enter Your E-mail Address';
}
;
},
onSaved: (val) {
_email = val;
},
),
TextFormField(
autofocus: false,
obscureText: true,
decoration: InputDecoration(
icon: Icon(Icons.vpn_key),
hintText: 'Enter Your Password',
),
validator: (val) {
if (val.isEmpty) {
return 'Enter Your Password';
} else if (val.length < 6) {
return 'Your Password need to be at least 6 characters';
}
;
},
onSaved: (val) {
_password = val;
},
),
RaisedButton(
child: Text('Login'),
onPressed: () async {
final formdata = formState.currentState;
if (formdata.validate()) {
final FirebaseAuth _auth = FirebaseAuth.instance;
formdata.save();
AuthResult result = await _auth.signInWithEmailAndPassword(
email: _email, password: _password)
.catchError((error) => print(error.code));
if (result != null) {
FirebaseUser user = result.user;
if (user != null) {
print('Log In: $user');
}
;
}
;
}
;
},
color: Colors.deepOrange,
textColor: Colors.white,
),
],
),
),
),
],
),
),
],
),
);
}
}
i have updated My question i have provided full code why i'm getting message of invalid email should i remove strings at first or remove _email _password from string

Resources