Flutter es una herramienta increíble para desarrollar aplicaciones multiplataforma utilizando una única base de código. Si bien Flutter es útil, se vuelve aún mejor cuando agrega Firebase. En este artículo, discutiremos cómo implementar el proceso de autenticación de correo electrónico/contraseña en Flutter, usando Firebase.
En este artículo, cubriremos los siguientes aspectos del desarrollo de aleteo:
Dart
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_auth_example/models/user_model.dart'; class AuthenticationService { final FirebaseAuth _firebaseAuth; UserModel userModel = UserModel(); final userRef = Firestore.instance.collection("users"); AuthenticationService(this._firebaseAuth); // managing the user state via stream. // stream provides an immediate event of // the user's current authentication state, // and then provides subsequent events whenever // the authentication state changes. Stream<User> get authStateChanges => _firebaseAuth.authStateChanges(); //1 Future<String> signIn({String email, String password}) async { try { await _firebaseAuth.signInWithEmailAndPassword( email: email, password: password); return "Signed In"; } on FirebaseAuthException catch (e) { if (e.code == 'user-not-found') { return "No user found for that email."; } else if (e.code == 'wrong-password') { return "Wrong password provided for that user."; } else { return "Something Went Wrong."; } } } //2 Future<String> signUp({String email, String password}) async { try { await _firebaseAuth.createUserWithEmailAndPassword( email: email, password: password); return "Signed Up"; } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { return "The password provided is too weak."; } else if (e.code == 'email-already-in-use') { return "The account already exists for that email."; } else { return "Something Went Wrong."; } } catch (e) { print(e); } } //3 Future<void> addUserToDB( {String uid, String username, String email, DateTime timestamp}) async { userModel = UserModel( uid: uid, username: username, email: email, timestamp: timestamp); await userRef.document(uid).setData(userModel.toMap(userModel)); } //4 Future<UserModel> getUserFromDB({String uid}) async { final DocumentSnapshot doc = await userRef.document(uid).get(); //print(doc.data()); return UserModel.fromMap(doc.data()); } //5 Future<void> signOut() async { await _firebaseAuth.signOut(); } }
Dart
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; class UserModel { String email; String uid; String username; DateTime timestamp; UserModel({this.email, this.uid, this.username, this.timestamp}); Map toMap(UserModel user) { var data = Map<String, dynamic>(); data["uid"] = user.uid; data["username"] = user.username; data["email"] = user.email; data["timestamp"] = user.timestamp; return data; } UserModel.fromMap(Map<String, dynamic> mapData) { this.uid = mapData["uid"]; this.username = mapData["username"]; this.email = mapData["email"]; } }
Dart
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_auth_example/pages/auth_screen_view.dart'; import 'package:flutter_auth_example/pages/home_page.dart'; import 'package:flutter_auth_example/services/authentication_service.dart'; import 'package:provider/provider.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider<AuthenticationService>( create: (_) => AuthenticationService(FirebaseAuth.instance), ), StreamProvider( create: (context) => context.read<AuthenticationService>().authStateChanges), ], child: MaterialApp( theme: ThemeData( brightness: Brightness.dark, primaryColor: Colors.green[400], accentColor: Colors.deepOrange[200]), home: AuthenticationWrapper(), ), ); } } class AuthenticationWrapper extends StatelessWidget { @override Widget build(BuildContext context) { final firebaseUser = context.watch<User>(); if (firebaseUser != null) { //If the user is successfully Logged-In. return HomePage(); } else { //If the user is not Logged-In. return AuthScreenView(); } } }
Dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_auth_example/pages/login_page.dart'; import 'package:flutter_auth_example/pages/register_page.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class AuthScreenView extends StatefulWidget { @override _AuthScreenViewState createState() => _AuthScreenViewState(); } class _AuthScreenViewState extends State<AuthScreenView> { PageController pageController; int pageIndex = 0; @override void initState() { // TODO: implement initState super.initState(); pageController = PageController(); } @override void dispose() { // TODO: implement dispose super.dispose(); pageController.dispose(); } onPageChanged(int pageIndex) { setState(() { this.pageIndex = pageIndex; }); } onTap(int pageIndex) { //pageController.jumpToPage(pageIndex); pageController.animateToPage(pageIndex, duration: Duration(milliseconds: 300), curve: Curves.easeInOut); } @override Widget build(BuildContext context) { return Scaffold( body: PageView( children: [ //when pageIndex == 0 LoginPage(), //when pageIndex == 1 RegisterPage() ], controller: pageController, onPageChanged: onPageChanged, ), bottomNavigationBar: CupertinoTabBar( currentIndex: pageIndex, onTap: onTap, activeColor: Theme.of(context).primaryColor, items: [ BottomNavigationBarItem( title: Text("Log-In"), icon: Icon( FontAwesomeIcons.signInAlt, )), BottomNavigationBarItem( title: Text("Register"), icon: Icon( FontAwesomeIcons.userPlus, )), ], ), ); } }
Dart
import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_auth_example/services/authentication_service.dart'; import 'package:provider/provider.dart'; class RegisterPage extends StatefulWidget { @override _RegisterPageState createState() => _RegisterPageState(); } class _RegisterPageState extends State<RegisterPage> { //To Toggle Password Text Visibility. bool _obscureText = true; String _username, _email, _password; //For the loading state. bool _isSubmitting; final _formKey = GlobalKey<FormState>(); final _scaffoldKey = GlobalKey<ScaffoldState>(); FirebaseAuth auth = FirebaseAuth.instance; final DateTime timestamp = DateTime.now(); @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar(title: Text("GeeksForGeeks"), centerTitle: true), body: Container( padding: EdgeInsets.symmetric(horizontal: 20), child: Center( child: SingleChildScrollView( child: Form( key: _formKey, child: Column( children: [ _showTitle(), _showUsernameInput(), _showEmailInput(), _showPasswordInput(), _showFormActions() ], ), ), ), ), ), ); } //1 _showTitle() { return Text( "Register", style: TextStyle(fontSize: 72, fontWeight: FontWeight.bold), ); } //2 _showUsernameInput() { return Padding( padding: EdgeInsets.only(top: 20), child: TextFormField( onSaved: (val) => _username = val, validator: (val) => val.length < 6 ? "Username is too short." : null, decoration: InputDecoration( border: OutlineInputBorder(), labelText: "Username", hintText: "Enter Valid Username", icon: Icon( Icons.face, color: Colors.grey, )), ), ); } //3 _showEmailInput() { return Padding( padding: EdgeInsets.only(top: 20), child: TextFormField( onSaved: (val) => _email = val, validator: (val) => !val.contains("@") ? "Invalid Email" : null, decoration: InputDecoration( border: OutlineInputBorder(), labelText: "Email", hintText: "Enter Valid Email", icon: Icon( Icons.mail, color: Colors.grey, )), ), ); } //4 _showPasswordInput() { return Padding( padding: EdgeInsets.only(top: 20), child: TextFormField( onSaved: (val) => _password = val, validator: (val) => val.length < 6 ? "Password Is Too Short" : null, obscureText: _obscureText, decoration: InputDecoration( suffixIcon: GestureDetector( onTap: () { setState(() { _obscureText = !_obscureText; }); }, child: Icon(_obscureText ? Icons.visibility_off : Icons.visibility), ), border: OutlineInputBorder(), labelText: "Password", hintText: "Enter Valid Password", icon: Icon( Icons.lock, color: Colors.grey, )), ), ); } //5 _showFormActions() { return Padding( padding: EdgeInsets.only(top: 20), child: Column( children: [ _isSubmitting == true ? CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Theme.of(context).primaryColor), ) : RaisedButton( child: Text( "Submit", style: TextStyle(color: Colors.black, fontSize: 18), ), elevation: 8.0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10))), color: Colors.orange, onPressed: _submit), ], ), ); } //6 _submit() { final _form = _formKey.currentState; if (_form.validate()) { _form.save(); //print("Email $_email, Password $_password, Username $_username"); _registerUser(); } else { print("Form is Invalid"); } } //7 _registerUser() async { setState(() { _isSubmitting = true; }); final logMessage = await context .read<AuthenticationService>() .signUp(email: _email, password: _password); logMessage == "Signed Up" ? _showSuccessSnack(logMessage) : _showErrorSnack(logMessage); print(logMessage); if (logMessage == "Signed Up") { createUserInFirestore(); } else { setState(() { _isSubmitting = false; }); } } //When User "Signed Up", success snack will display. _showSuccessSnack(String message) { final snackbar = SnackBar( backgroundColor: Colors.black, content: Text( "$message", style: TextStyle(color: Colors.green), ), ); _scaffoldKey.currentState.showSnackBar(snackbar); _formKey.currentState.reset(); } //When FirebaseAuth Catches error, error snack will display. _showErrorSnack(String message) { final snackbar = SnackBar( backgroundColor: Colors.black, content: Text( "$message", style: TextStyle(color: Colors.red), ), ); _scaffoldKey.currentState.showSnackBar(snackbar); } createUserInFirestore() async { context.read<AuthenticationService>().addUserToDB( uid: auth.currentUser.uid, username: _username, email: auth.currentUser.email, timestamp: timestamp); } }
Dart
import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_auth_example/services/authentication_service.dart'; import 'package:provider/provider.dart'; class LoginPage extends StatefulWidget { @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { bool _obscureText = true; String _email, _password; bool _isSubmitting; final _formKey = GlobalKey<FormState>(); final _scaffoldKey = GlobalKey<ScaffoldState>(); FirebaseAuth auth = FirebaseAuth.instance; final DateTime timestamp = DateTime.now(); @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar( centerTitle: true, title: Text("GeeksForGeeks"), ), body: Container( padding: EdgeInsets.symmetric(horizontal: 20), child: Center( child: SingleChildScrollView( child: Form( key: _formKey, child: Column( children: [ _showTitle(), _showEmailInput(), _showPasswordInput(), _showFormActions() ], ), ), ), ), ), ); } _showTitle() { return Text( "Login", style: TextStyle(fontSize: 72, fontWeight: FontWeight.bold), ); } _showEmailInput() { return Padding( padding: EdgeInsets.only(top: 20), child: TextFormField( onSaved: (val) => _email = val, validator: (val) => !val.contains("@") ? "Invalid Email" : null, decoration: InputDecoration( border: OutlineInputBorder(), labelText: "Email", hintText: "Enter Valid Email", icon: Icon( Icons.mail, color: Colors.grey, )), ), ); } _showPasswordInput() { return Padding( padding: EdgeInsets.only(top: 20), child: TextFormField( onSaved: (val) => _password = val, validator: (val) => val.length < 6 ? "Password Is Too Short" : null, obscureText: _obscureText, decoration: InputDecoration( suffixIcon: GestureDetector( onTap: () { setState(() { _obscureText = !_obscureText; }); }, child: Icon(_obscureText ? Icons.visibility_off : Icons.visibility), ), border: OutlineInputBorder(), labelText: "Password", hintText: "Enter Valid Password", icon: Icon( Icons.lock, color: Colors.grey, )), ), ); } _showFormActions() { return Padding( padding: EdgeInsets.only(top: 20), child: Column( children: [ _isSubmitting == true ? CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Theme.of(context).primaryColor), ) : RaisedButton( child: Text( "Submit", style: TextStyle(color: Colors.black, fontSize: 18), ), elevation: 8.0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10))), color: Colors.orange, onPressed: _submit), ], ), ); } _submit() { final _form = _formKey.currentState; if (_form.validate()) { _form.save(); //print("Email $_email, Password $_password"); _LoginUser(); } else { print("Form is Invalid"); } } _LoginUser() async { setState(() { _isSubmitting = true; }); final logMessage = await context .read<AuthenticationService>() .signIn(email: _email, password: _password); logMessage == "Signed In" ? _showSuccessSnack(logMessage) : _showErrorSnack(logMessage); //print("I am logMessage $logMessage"); if (logMessage == "Signed In") { return; } else { setState(() { _isSubmitting = false; }); } } _showSuccessSnack(String message) async { final snackbar = SnackBar( backgroundColor: Colors.black, content: Text( "$message", style: TextStyle(color: Colors.green), ), ); _scaffoldKey.currentState.showSnackBar(snackbar); _formKey.currentState.reset(); } _showErrorSnack(String message) { final snackbar = SnackBar( backgroundColor: Colors.black, content: Text( "$message", style: TextStyle(color: Colors.red), ), ); _scaffoldKey.currentState.showSnackBar(snackbar); setState(() { _isSubmitting = false; }); } }
Dart
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_auth_example/models/user_model.dart'; import 'package:flutter_auth_example/services/authentication_service.dart'; import 'package:provider/provider.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { FirebaseAuth auth = FirebaseAuth.instance; final userRef = Firestore.instance.collection("users"); UserModel _currentUser; String _uid; String _username; String _email; @override void initState() { // TODO: implement initState super.initState(); getCurrentUser(); } getCurrentUser() async { UserModel currentUser = await context .read<AuthenticationService>() .getUserFromDB(uid: auth.currentUser.uid); _currentUser = currentUser; print("${_currentUser.username}"); setState(() { _uid = _currentUser.uid; _username = _currentUser.username; _email = _currentUser.email; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("HomePage"), centerTitle: true, ), body: _currentUser == null ? Center(child: CircularProgressIndicator()) : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "uid is ${_uid} , email is ${_email}, name is ${_username}", textAlign: TextAlign.center, ), Center( child: RaisedButton( child: Text( "Logout", style: TextStyle(color: Colors.black, fontSize: 18), ), elevation: 8.0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(10))), color: Colors.orange, onPressed: () { context.read<AuthenticationService>().signOut(); }, ), ), ], ), ); } }
Publicación traducida automáticamente
Artículo escrito por aniketambore y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA