I'm following a flutter firebase tutorial, and now i'm trying to verify my signing using Email , the problem is that it does not seem to work , and when i try to verify again , it gives me an FirebaseauthException cause i'm trying too much (as the exception said) to verify the email , which may be weird to FireBase , but why isn't working in the first time,
here is the code , i've tried to print some thing after the line that should send the request to verify , and it worked! :
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
#override
State<Test> createState() => MyState();
}
class MyState extends State<Test> {
UserCredential? usercredential;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Test")),
body: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Center(
child: RaisedButton(
onPressed: () async {
try {
usercredential = await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: 'hamzafz888#gmail.com',
password: "verysecretpassword!");
print("Signed in with temporary account.");
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') print("no user in this email");
if (e.code == 'wrong-password') print("wrong password inserted");
} catch (e) {
print("UNKOWN ERROR");
}
// print(usercredential!.user!.emailVerified);
if (!usercredential!.user!.emailVerified) {
User? user1 = FirebaseAuth.instance.currentUser;
await user1!.sendEmailVerification();
//print("hello");
}
},
child: Text("Sign In"),
))
]),
);
}
}
Related
I have made signup and login pages, and they work perfect, but now I am trying to create a Profile page, but when I try to add Navigator or put the home in main.dart as Profile page, it doesn't work:
Main.dart:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:mypocket/telas/perfil/Perfil.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Pocket',
debugShowCheckedModeBanner: false,
theme: ThemeData(
),
home: Perfil(user: user,),
);
}
}
Perfil.dart:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:mypocket/controllers/firebase_auth.dart';
import 'package:mypocket/controllers/validator.dart';
class Perfil extends StatefulWidget {
final User user;
Perfil({required this.user});
#override
_PerfilState createState() => _PerfilState();
}
class _PerfilState extends State<Perfil> {
late User _currentUser;
#override
void initState(){
_currentUser = widget.user;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 92, 172, 178),
centerTitle: true,
title: Text('Perfil'),
toolbarHeight: 90,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40)
),
elevation: 15,
),
body: Container(
padding: EdgeInsets.all(32),
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
],
),
),
);
}
}
And this is firebase_auth.dart, created to make the authentication of the login and register pages:
import 'package:firebase_auth/firebase_auth.dart';
class FirebaseAuthHelper {
static Future<User?> registerUsingEmailPassword({
required String name,
required String email,
required String password,
}) async {
FirebaseAuth auth = FirebaseAuth.instance;
User? user;
try {
UserCredential userCredential = await auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
user = userCredential.user;
await user!.updateProfile(displayName: name);
await user.reload();
user = auth.currentUser;
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
return user;
}
Also, if I remove user: user, it still doesn't work:
First of all, you have not created the instance of the User. To create that you can create using this.
class FirebaseAuthHelper {
FirebaseAuthHelper._();
static final instance = FirebaseAuthHelper._();
FirebaseAuth firebaseAuth = FirebaseAuth.instance;
Future<User?> registerUsingEmailPassword({
required String name,
required String email,
required String password,
}) async {
FirebaseAuth auth = FirebaseAuth.instance;
User? user;
try {
UserCredential userCredential = await
auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
user = userCredential.user;
await user!.updateProfile(displayName: name);
await user.reload();
user = auth.currentUser;
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
return user;
}
I would suggest create a singleton class of your FirebaseAuthHelper so that you do not need to add a static keyword every time you can access any method of the class like this final auth = FirebaseAuthHelper.instance.
To access the method you just need to call it like this auth.registerUsingEmailPassword(parameters).
To get an instance of the User you can do like this
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:mypocket/telas/perfil/Perfil.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// widget is the root of your application.
final auth = FirebaseAuthHelper.instance
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Pocket',
debugShowCheckedModeBanner: false,
theme: ThemeData(
),
home: Perfil(user:auth.firebaseAuth.currentUser),// To get current user
);
}
}
I hope this will help you
I am trying to apply conditions on widget when user is logged in, display widget logout else display login button.How is it possible?
Before login
After Login
I used shred_preferences package saving, getting and removing used data.
Here my codes:
shared_preferences
import 'package:shared_preferences/shared_preferences.dart';
class PrefServices{
Future createCache(String username, String password) async {
SharedPreferences _preferences = await SharedPreferences.getInstance();
_preferences.setString("username", username);
_preferences.setString("password", password);
}
Future readCache(String username) async {
SharedPreferences _preferences = await SharedPreferences.getInstance();
var username = _preferences.getString("username")?? "null";
// _preferences.getString("password");
return username;
}
Future<void> removeCache(String username, String password) async {
SharedPreferences _preferences = await SharedPreferences.getInstance();
_preferences.remove("username");
_preferences.remove("password");
}
}
Profile Screen
import 'dart:async';
import 'package:clothing_roll/shred_preferences/shred_preferences_services.dart';
import 'package:clothing_roll/ui/widget/profile/login_widget.dart';
import 'package:clothing_roll/ui/widget/profile/profiles_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ProfileScreen extends StatefulWidget {
const ProfileScreen({ Key? key }) : super(key: key);
#override
_ProfileScreen createState() => _ProfileScreen();
}
class _ProfileScreen extends State<ProfileScreen> {
final PrefServices _prefServices = PrefServices();
#override
void initState() {
_prefServices.readCache("username").then((value) {
print(value.toString());
if (value != null) {
return Timer(Duration(seconds: 1),
() => ProfileWidget());
} else {
return Timer(Duration(seconds: 1),
() => LoginWidget());
}
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Container();
}
}
Note: I have used Getx package
create a bool variable for conmdition check
add ternary operator to bool variable and change the conditions
class Test1 extends StatelessWidget {
Controller controller = Get.put(Controller());
Test1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
width: Get.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
controller.isLogged.value = !controller.isLogged.value;
},
child: Text("Press to change value")),
Obx(
() => controller.isLogged.value
? ElevatedButton(onPressed: () {}, child: Text("logged In"))
: ElevatedButton(onPressed: () {}, child: Text("Logged Out")),
),
],
),
),
);
}
}
I have successfully implemented the flutter_secure_storage in my flutter project, when the user writes his email and password, it get's stored, but here is the thing I don't understand. How should I setup screen routes depending if the user has already logged in or not. If it is the same user, so the username and pass are stored in the secure_storage, I want him to go directly to HomeScreen(), but if there is a new user that needs to log in, so there is no data in the secure_storage, then I want him sent to LoginScreen(). I have done this so far:
import 'dart:async';
import 'package:flutter/material.dart';
import 'login_screen.dart';
import 'home_screen.dart';
import 'components/alarm_buttons.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class WelcomeScreen extends StatefulWidget {
static const String id = 'welcome_screen';
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
void readData() async {
final storage = FlutterSecureStorage();
String myPassword = await storage.read(key: "p");
String myEmail = await storage.read(key: "e");
print(myEmail);
print(myPassword);
}
#override
void initState() {
final storage = FlutterSecureStorage();
Timer(
Duration(seconds: 2),
() => Navigator.pushNamed(
context,
storage == null ? LoginScreen.id : HomePage.id,
));
readData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
AlarmButtons(
buttonColour: Colors.grey,
buttonText: 'Log In',
buttonTextColour: Colors.white,
onButtonPress: () {
Navigator.pushNamed(context, LoginScreen.id);
},
),
AlarmButtons(
buttonColour: Colors.white,
buttonText: 'Sign up',
buttonTextColour: Colors.grey,
onButtonPress: () {
Navigator.pushNamed(context, SignUpScreen.id);
},
),
],
),
),
);
}
}
Now the problem starts when I want to return to the Welcome Screen (the starting page of my app shown above), naturally it triggers the initState again and I get back to the HomePage() again. How can I dispose of that, only triggering that initState when the app starts, so after automatic login I can return to the Welcome Screen without triggering it?
Thanks in advance!
You should initial start something like a SplashScreen (or WelcomeScreen in your case). There you can decide to which screen you want to navigate based on the saved data. Example:
class SplashScreen extends StatefulWidget {
const SplashScreen({Key key}) : super(key: key);
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
#override
void initState() {
_startApp();
super.initState();
}
Future<void> _startApp() async {
final storage = FlutterSecureStorage();
String myEmail = await storage.read(key: "e");
if (myEmail == null) {
// TODO Navigate to Login Screen
} else {
// TODO Navigate to Home Screen
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Splashscreen"),
),
);
}
}
I'm unsure of how to incorporate this into an existing flutter project and I haven't been able to find any useful guides or tips online. Im looking to implement a 2D only barcode scanner, and none of the existing flutter barcode scanners have that option.
I know ZXing also has the 2d only functionality in it so I could be swayed to use that if anyone can point me in the direction of how to implement them in flutter
Please check this url
https://pub.dartlang.org/packages/qrcode_reader
Here is implementation code
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:qrcode_reader/QRCodeReader.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'QRCode Reader Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
final Map<String, dynamic> pluginParameters = {
};
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> _barcodeString;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('QRCode Reader Example'),
),
body: new Center(
child: new FutureBuilder<String>(
future: _barcodeString,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
return new Text(snapshot.data != null ? snapshot.data : '');
})),
floatingActionButton: new FloatingActionButton(
onPressed: () {
setState(() {
_barcodeString = new QRCodeReader()
.setAutoFocusIntervalInMs(200)
.setForceAutoFocus(true)
.setTorchEnabled(true)
.setHandlePermissions(true)
.setExecuteAfterPermissionGranted(true)
.scan();
});
},
tooltip: 'Reader the QRCode',
child: new Icon(Icons.add_a_photo),
),
);
}
}
This can be done by using flutter barcode_scan dependency.
Future _openQRScanner() async {
try {
// Below code will open camera preview and return result after qr scan
String _content = await BarcodeScanner.scan();
setState(() => this._content = _content);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
showSnackBar('Please grant camera permission!');
setState(() {
this._content = null;
});
} else {
showSnackBar('Error: $e');
setState(() {
this._content = null;
});
}
} on FormatException {
showSnackBar('User pressed "back" button before scanning');
setState(() {
this._content = null;
});
} catch (e) {
showSnackBar('Error: $e');
setState(() {
this._content = null;
});
}
}
Please find the repo.
If you want to take a look at Flutter you can find some good examples at our companie’s Github page. Also, you can check our company's page FlutterDevs.
I have a raised button that kicks off my fingerprint authentication, when the Future returns I want to be able to change the Raised Button to new text and new onPressed method to complete the required authentication. I have given the Raised Button a key but can not find how to act upon that button to change it. Is it possible? Anyone have examples of it?
I tried to create new Raised Button with same key based on if the user is authenticated, but it did not change anything.
Any help would be great.
I would recommend reviewing the Flutter Interactivity Tutorial.
Once the Future completes you can call setState to tell Flutter to rebuild your StatefulWidget. And in your build() method, you can use the authenticated status of the user to construct a different RaisedButton.
Here's some example code that does this:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Local Auth Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _authenticated = false;
Future<Null> _authenticate() async {
final LocalAuthentication auth = new LocalAuthentication();
bool authenticated = false;
try {
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true);
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_authenticated = authenticated;
});
}
Widget _buildAuthButton() {
assert(!_authenticated);
return new RaisedButton(
child: new Text('Authenticate'),
onPressed: _authenticate,
);
}
Widget _buildContinueButton() {
assert(_authenticated);
return new RaisedButton(
child: new Text('Continue'),
onPressed: () {
// Do something now that the user is authenticated
},
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Interactivity Tutoral'),
),
body: new Center(
child: _authenticated ? _buildContinueButton() : _buildAuthButton(),
),
);
}
}
I would use FutureBuilder, just return one widget or the other based on whether the Future is complete
new FutureBuilder<String>(
future: your_future,
builder: (_, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text(
'Your data: ${snapshot.data}',
);
}
})